Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
wyvern.qc
Go to the documentation of this file.
1#include "wyvern.qh"
2
3#ifdef SVQC
16
19
20SOUND(WyvernAttack_FIRE, W_Sound("electro_fire"));
21METHOD(WyvernAttack, wr_think, void(WyvernAttack thiswep, entity actor, .entity weaponentity, int fire))
22{
23 TC(WyvernAttack, thiswep);
24 if (fire & 1)
25 if (time > actor.attack_finished_single[0] || weapon_prepareattack(thiswep, actor, weaponentity, false, 1.2)) {
26 monster_makevectors(actor, actor.enemy);
27 if (IS_PLAYER(actor)) W_SetupShot_Dir(actor, weaponentity, v_forward, false, 0, SND_WyvernAttack_FIRE, CH_WEAPON_B, 0, DEATH_MONSTER_WYVERN.m_id);
28 if (IS_MONSTER(actor)) {
29 actor.attack_finished_single[0] = time + 1.2;
30 actor.anim_finished = time + 1.2;
31 }
32
33 entity missile = new(WyvernAttack);
34 missile.owner = missile.realowner = actor;
35 missile.solid = SOLID_TRIGGER;
37 missile.projectiledeathtype = DEATH_MONSTER_WYVERN.m_id;
38 setsize(missile, '-6 -6 -6', '6 6 6');
39 setorigin(missile, actor.origin + actor.view_ofs + v_forward * 14);
40 missile.flags = FL_PROJECTILE;
41 IL_PUSH(g_projectiles, missile);
42 IL_PUSH(g_bot_dodge, missile);
44 missile.avelocity = '300 300 300';
45 missile.nextthink = time + 5;
48 CSQCProjectile(missile, true, PROJECTILE_FIREMINE, true);
49
50 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, w_ready);
51 }
52}
53
54METHOD(WyvernAttack, wr_checkammo1, bool(WyvernAttack this, entity actor, .entity weaponentity)) {
55 TC(WyvernAttack, this);
56 return true;
57}
58
60{
61 Send_Effect(EFFECT_FIREBALL_EXPLODE, this.origin, '0 0 0', 1);
62
63 entity own = this.realowner;
64
67
69 {
70 Fire_AddDamage(it, own, 5 * MONSTER_SKILLMOD(own), autocvar_g_monster_wyvern_attack_fireball_damagetime, this.projectiledeathtype);
71 });
72
73 delete(this);
74}
75
82
84{
85 w_shotdir = normalize((this.enemy.origin + '0 0 10') - this.origin);
86 Weapon wep = WEP_WYVERN_ATTACK;
87 // TODO
88 .entity weaponentity = weaponentities[0];
89 wep.wr_think(wep, this, weaponentity, 1);
90}
91
92bool M_Wyvern_Attack(int attack_type, entity actor, entity targ, .entity weaponentity)
93{
94 switch(attack_type)
95 {
98 {
100 //actor.anim_finished = time + 1.2;
101 setanim(actor, actor.anim_shoot, false, true, true);
102 if(actor.animstate_endtime > time)
103 actor.anim_finished = actor.animstate_endtime;
104 else
105 actor.anim_finished = time + 1.2;
106 actor.attack_finished_single[0] = actor.anim_finished + 0.2;
107 return true;
108 }
109 }
110
111 return false;
112}
113
114spawnfunc(monster_wyvern) { Monster_Spawn(this, true, MON_WYVERN); }
115#endif // SVQC
116
117#ifdef SVQC
118METHOD(Wyvern, mr_think, bool(Wyvern this, entity actor))
119{
120 TC(Wyvern, this);
121 return true;
122}
123
124METHOD(Wyvern, mr_deadthink, bool(Wyvern this, entity actor))
125{
126 TC(Wyvern, this);
127 if(IS_ONGROUND(actor))
128 setanim(actor, actor.anim_die2, true, false, false);
129 return true;
130}
131
132METHOD(Wyvern, mr_pain, float(Wyvern this, entity actor, float damage_take, entity attacker, float deathtype))
133{
134 TC(Wyvern, this);
135 actor.pain_finished = time + 0.5;
136 setanim(actor, actor.anim_pain1, true, true, false);
137 return damage_take;
138}
139
140METHOD(Wyvern, mr_death, bool(Wyvern this, entity actor))
141{
142 TC(Wyvern, this);
143 setanim(actor, actor.anim_die1, false, true, true);
144 actor.velocity_x = -200 + 400 * random();
145 actor.velocity_y = -200 + 400 * random();
146 actor.velocity_z = 100 + 100 * random();
147 return true;
148}
149#endif
150#ifdef GAMEQC
151METHOD(Wyvern, mr_anim, bool(Wyvern this, entity actor))
152{
153 TC(Wyvern, this);
154 vector none = '0 0 0';
155 actor.anim_idle = animfixfps(actor, '0 1 1', none);
156 actor.anim_walk = animfixfps(actor, '1 1 1', none);
157 actor.anim_run = animfixfps(actor, '2 1 1', none);
158 actor.anim_pain1 = animfixfps(actor, '3 1 2', none); // 0.5 seconds
159 actor.anim_pain2 = animfixfps(actor, '4 1 2', none); // 0.5 seconds
160 actor.anim_melee = animfixfps(actor, '5 1 5', none); // analyze models and set framerate
161 actor.anim_shoot = animfixfps(actor, '6 1 5', none); // analyze models and set framerate
162 actor.anim_die1 = animfixfps(actor, '7 1 0.5', none); // 2 seconds
163 actor.anim_die2 = animfixfps(actor, '8 1 0.5', none); // 2 seconds
164 return true;
165}
166#endif
167#ifdef SVQC
168METHOD(Wyvern, mr_setup, bool(Wyvern this, entity actor))
169{
170 TC(Wyvern, this);
171 if(!GetResource(this, RES_HEALTH)) SetResourceExplicit(actor, RES_HEALTH, autocvar_g_monster_wyvern_health);
172 if(!actor.speed) { actor.speed = (autocvar_g_monster_wyvern_speed_walk); }
173 if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_wyvern_speed_run); }
174 if(!actor.stopspeed) { actor.stopspeed = (autocvar_g_monster_wyvern_speed_stop); }
175 if(!actor.damageforcescale) { actor.damageforcescale = (autocvar_g_monster_wyvern_damageforcescale); }
176
177 actor.monster_loot = autocvar_g_monster_wyvern_loot;
178 actor.monster_attackfunc = M_Wyvern_Attack;
179
180 return true;
181}
182#endif
183#ifdef MENUQC
184METHOD(Wyvern, describe, string(Wyvern this))
185{
186 TC(Wyvern, this);
188 PAR(_("The Wyvern is a flying reptilian monster that glides around hunting for fresh prey."));
189 PAR(_("While fragile, the Wyvern is capable of launching deadly fireballs at the player from a distance, inflicting high damage and causing burning."));
190 return PAGE_TEXT;
191}
192#endif
#define setanim(...)
Definition anim.qh:45
IntrusiveList g_bot_dodge
Definition api.qh:150
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition weapon.qh:44
virtual void wr_think()
(SERVER) logic to run every frame
Definition weapon.qh:90
#define IS_PLAYER(s)
Definition player.qh:243
const int FL_PROJECTILE
Definition constants.qh:85
const float SOLID_TRIGGER
float time
vector v_forward
vector origin
void CSQCProjectile(entity e, float clientanimate, int type, float docull)
float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype,.entity weaponentity, entity directhitentity)
Definition damage.qc:981
#define DMG_NOWEP
Definition damage.qh:104
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:124
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define FOREACH_ENTITY_RADIUS(org, dist, cond, body)
Definition iter.qh:160
#define TC(T, sym)
Definition _all.inc:82
float random(void)
vector normalize(vector v)
vector animfixfps(entity e, vector a, vector b)
Definition util.qc:1808
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_FLYMISSILE
Definition movetypes.qh:138
#define IS_ONGROUND(s)
Definition movetypes.qh:16
#define METHOD(cname, name, prototype)
Definition oo.qh:269
#define NULL
Definition post.qh:14
const int PROJECTILE_FIREMINE
#define setthink(e, f)
vector
Definition self.qh:92
entity entity toucher
Definition self.qh:72
#define settouch(e, f)
Definition self.qh:73
int projectiledeathtype
Definition common.qh:21
#define PROJECTILE_TOUCH(e, t)
Definition common.qh:28
IntrusiveList g_projectiles
Definition common.qh:58
const int CH_WEAPON_B
Definition sound.qh:8
string W_Sound(string w_snd)
Definition all.qc:225
#define SOUND(name, path)
Definition all.qh:30
#define spawnfunc(id)
Definition spawnfunc.qh:96
#define PAGE_TEXT
Definition string.qh:643
#define PAR(...)
Adds an individually translatable paragraph to PAGE_TEXT without having to deal with strcat and sprin...
Definition string.qh:649
#define PAGE_TEXT_INIT()
Definition string.qh:642
const int DAMAGE_AIM
Definition subs.qh:81
entity enemy
Definition sv_ctf.qh:153
void Monster_Delay(entity this, int repeat_count, float defer_amnt, void(entity) func)
bool Monster_Spawn(entity this, bool check_appear, Monster mon)
void monster_makevectors(entity this, entity targ)
const int MONSTER_ATTACK_MELEE
const int MONSTER_ATTACK_RANGED
entity realowner
vector w_shotdir
Definition tracing.qh:20
#define W_SetupShot_Dir(ent, wepent, s_forward, antilag, recoil, snd, chan, maxdamage, deathtype)
Definition tracing.qh:32
#define IS_MONSTER(v)
Definition utils.qh:21
entity weaponentities[MAX_WEAPONSLOTS]
Definition weapon.qh:17
void weapon_thinkf(entity actor,.entity weaponentity, WFRAME fr, float t, void(Weapon thiswep, entity actor,.entity weaponentity, int fire) func)
bool weapon_prepareattack(Weapon thiswep, entity actor,.entity weaponentity, bool secondary, float attacktime)
void w_ready(Weapon thiswep, entity actor,.entity weaponentity, int fire)
float autocvar_g_monster_wyvern_attack_fireball_damage
Definition wyvern.qc:7
float autocvar_g_monster_wyvern_health
Definition wyvern.qc:4
string autocvar_g_monster_wyvern_loot
Definition wyvern.qc:5
float autocvar_g_monster_wyvern_speed_stop
Definition wyvern.qc:13
bool M_Wyvern_Attack(int attack_type, entity actor, entity targ,.entity weaponentity)
Definition wyvern.qc:92
float autocvar_g_monster_wyvern_attack_fireball_edgedamage
Definition wyvern.qc:8
float autocvar_g_monster_wyvern_speed_walk
Definition wyvern.qc:15
void M_Wyvern_Attack_Fireball_Touch(entity this, entity toucher)
Definition wyvern.qc:76
float autocvar_g_monster_wyvern_speed_run
Definition wyvern.qc:14
void M_Wyvern_Attack_Fireball_Explode(entity this)
Definition wyvern.qc:59
float autocvar_g_monster_wyvern_damageforcescale
Definition wyvern.qc:6
float autocvar_g_monster_wyvern_attack_fireball_force
Definition wyvern.qc:10
void M_Wyvern_Attack_Fireball(entity this)
Definition wyvern.qc:83
float autocvar_g_monster_wyvern_attack_fireball_radius
Definition wyvern.qc:11
float autocvar_g_monster_wyvern_attack_fireball_damagetime
Definition wyvern.qc:9
float autocvar_g_monster_wyvern_attack_fireball_speed
Definition wyvern.qc:12