#ifdef SSQC

#include "mapentity.h"

#define FUNC_WALL_SPAWNFIELDS(v) \
    SPAWNFIELD_PARSEINT(spawnflags, v) \
    SPAWNFIELD_PARSEINT(state_default, v)

// Reki (May 30 2024): Porting this and removing some field reuse
class func_wall : map_entity_c
{
    func_wall();
	
    virtual void GuardedConstructor();

	// Our logic functions
	nonvirtual void activation(void); // our targetname was poked (.use and .deuse)
	nonvirtual void reset(void); // reset_func
	nonvirtual void alphafade(void); // fade over time
	nonvirtual void unhide(void); // make visible and solid
	nonvirtual void hide(void); // make invisible and nonsolid

	// Parses fields set in editor
	virtual void ParseSpawnField(string key, string value);
	virtual void DefaultSpawnFields(void);

	// Fields
	//float spawnflags; <- inherited
	//int state; <- inherited, this is how ents like target_off detect if an ent is considering itself "on" or "off" so it must remain in the base-entity
	int state_current;
	int state_default;
};

#define FUNC_PENETRATE_SPAWNFIELDS(v) \
    SPAWNFIELD_PARSEINT(spawnflags, v) \
	SPAWNFIELD_PARSESTRING(targetname, v)
	
void Serialize_func_penetrate(sizebuf_t *buf);
void Read_func_penetrate(sizebuf_t *buf);

class func_penetrate : map_entity_c
{
	func_penetrate();

	virtual void GuardedConstructor();

	virtual void ParseSpawnField(string key, string value);

	// Fields
	//float spawnflags; <- inherited
};

class func_illusionary : map_entity_c
{
	func_illusionary();

	virtual void GuardedConstructor();
};

class path_corner : map_entity_c
{
	path_corner();

	virtual void GuardedConstructor();
};

class trigger_hurt : map_entity_c
{
	trigger_hurt();

	virtual void GuardedConstructor();

	nonvirtual void trigger_hurt_touch();
};

class trigger_once : map_entity_c
{
	trigger_once();

	virtual void GuardedConstructor();

	nonvirtual void trigger_once_reset();
	nonvirtual void trigger_once_touch();
};

class trigger_multiple : map_entity_c
{
	trigger_multiple();

	virtual void GuardedConstructor();

	nonvirtual void trigger_multiple_reset();
	nonvirtual void trigger_multiple_touch();
};

// Info_Prop_Junk
// Reki (November 19 2024): This entity is for spawning junk items which get thrown,
// like during explosions or landing on trashcans

#define INFO_PROP_JUNK_SPAWNFIELDS(v) \
    SPAWNFIELD_PARSEINT(spawnflags, v) \
    SPAWNFIELD_PARSESTRING(model, v) \
    SPAWNFIELD_PARSESTRING(targetname, v) \
    SPAWNFIELD_REMAP_PARSEVEC3(throw_velocity, velocity, v) \
    SPAWNFIELD_PARSEINT(count, v)

class info_prop_junk : map_entity_c
{
	info_prop_junk();
	virtual void GuardedConstructor();

	// Parses fields set in editor
	virtual void ParseSpawnField(string key, string value);
	virtual void DefaultSpawnFields(void);

	// Methods
	nonvirtual void activation(void); // our targetname was poked (.use and .deuse)
	nonvirtual void reset(int rflags); // reset_func

	// Fields
	// int spawnflags; // <- inherited from base entity
	// int reset_flags; // <- inherited from base entity
	// string model; // <- inherited from base entity
	// string targetname; // <- inherited from base entity
	vector throw_velocity;
	int count;
};

#endif

// func_shootable
// Reki (December 4 2024): shootable entity

#define FUNC_SHOOTABLE_SPAWNFLAG_STAYSOLID 1

#ifdef SSQC
#define FUNC_SHOOTABLE_SPAWNFIELDS(v) \
	SPAWNFIELD_PARSEINT(spawnflags, v) \
	SPAWNFIELD_PARSEFLOAT(volume, v) \
	SPAWNFIELD_PARSEFLOAT(attenuation, v) \
	SPAWNFIELD_PARSESTRING(noise, v) \
	SPAWNFIELD_PARSESTRING(target, v) \
	SPAWNFIELD_PARSESTRING(targetname, v) \
    SPAWNFIELD_REMAP_PARSESTRING(model_alive, model, v) \
    SPAWNFIELD_REMAP_PARSESTRING(model_dead, model2, v) \
	SPAWNFIELD_PARSEINT(health, v)

class func_shootable : map_entity_c
{
	func_shootable();
	virtual void GuardedConstructor();

	// Parses fields set in editor
	virtual void ParseSpawnField(string key, string value);
	virtual void DefaultSpawnFields(void);

	// Methods
	nonvirtual float parsedamage(entity targ, entity attacker, trace_t *shot_trace, float *dflags, float *dvalue, vector *dknock);
	nonvirtual void die(void);
	nonvirtual void activation(void); // our targetname was poked (.use and .deuse)
	nonvirtual void reset(int rflags); // reset_func

	// Fields
	// int spawnflags; // <- inherited from base entity
	// int reset_flags; // <- inherited from base entity
	// string model; // <- inherited from base entity
	// string targetname; // <- inherited from base entity
	// string target; // <- inherited from base entity
	// float health; // <- inherited from base entity
	// float max_health; // <- inherited from base entity
	string model_alive;
	string model_dead;
};
class info_shootable : func_shootable {};
#endif

#ifdef CSQC
#define FUNC_SHOOTABLE_SPAWNFIELDS(v) \
	SPAWNFIELD_PARSEINT(spawnflags, v) \
	SPAWNFIELD_PARSEFLOAT(volume, v) \
	SPAWNFIELD_PARSEFLOAT(attenuation, v) \
	SPAWNFIELD_PARSESTRING(noise, v) \
	SPAWNFIELD_PARSESTRING(target, v) \
	SPAWNFIELD_PARSESTRING(targetname, v) \
    SPAWNFIELD_REMAP_PARSESTRING(model_alive, model, v) \
    SPAWNFIELD_REMAP_PARSESTRING(model_dead, model2, v) \
	SPAWNFIELD_PARSEINT(health, v)

class func_shootable_client : map_entity_c
{
	func_shootable_client();
	virtual void GuardedConstructor();

	// Parses fields set in editor
	virtual void ParseSpawnField(string key, string value);
	virtual void DefaultSpawnFields(void);

	// Methods
	nonvirtual float parsedamage(entity targ, entity attacker, trace_t *shot_trace, float *dflags, float *dvalue, vector *dknock);
	nonvirtual void die(void);
	nonvirtual void activation(void); // our targetname was poked (.use and .deuse)
	nonvirtual void reset(int rflags); // reset_func

	// Fields
	int spawnflags; // <- inherited from base entity
	// int reset_flags; // <- inherited from base entity
	// string model; // <- inherited from base entity
	// float health; // <- inherited from base entity
	float max_health; // <- not inherited in CSQC
	string model_alive;
	string model_dead;
};
class info_shootable_client : func_shootable_client {};
#endif