1acd8e0ab0cc65acafb5f2a6187b6d7a435af8be
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mapobjects / trigger / swamp.qc
1 #include "swamp.qh"
2 #if defined(CSQC)
3 #elif defined(MENUQC)
4 #elif defined(SVQC)
5     #include <lib/warpzone/util_server.qh>
6     #include <common/weapons/_all.qh>
7     #include <server/defs.qh>
8     #include <common/deathtypes/all.qh>
9 #endif
10
11 /*
12 *               t_swamp.c
13 *               Adds spawnfunc_trigger_swamp and suppoart routines for xonotic 1.2.1+
14 *               Author tZork (Jakob MG)
15 *               jakob@games43.se
16 *               2005 11 29
17 */
18
19 .float swamp_interval;  //Hurt players in swamp with this interval
20 .float swamp_slowdown;  //Players in swamp get slowd down by this mutch 0-1 is slowdown 1-~ is speedup (!?)
21 .entity swampslug;
22
23 #ifdef SVQC
24 spawnfunc(trigger_swamp);
25 #endif
26 void swamp_touch(entity this, entity toucher);
27 void swampslug_think(entity this);
28
29
30 /*
31 * Uses a entity calld swampslug to handle players in the swamp
32 * It works like this: When the plyer enters teh swamp the spawnfunc_trigger_swamp
33 * attaches a new "swampslug" to the player. As long as the plyer is inside
34 * the swamp the swamp gives the slug new health. But the slug slowly kills itself
35 * so when the player goes outside the swamp, it dies and releases the player from the
36 * swamps curses (dmg/slowdown)
37 *
38 * I do it this way becuz there is no "untouch" event.
39 */
40 void swampslug_think(entity this)
41 {
42         //Slowly kill the slug
43 #ifdef SVQC
44         SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - 1);
45 #elif defined(CSQC)
46         this.health -= 1;
47 #endif
48
49         //Slug dead? then remove curses.
50 #ifdef SVQC
51         if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
52 #elif defined(CSQC)
53         if(this.health <= 0)
54 #endif
55         {
56                 this.owner.in_swamp = 0;
57                 delete(this);
58                 //centerprint(this.owner,"Killing slug...\n");
59                 return;
60         }
61
62         // Slug still alive, so we are still in the swamp
63         // Or we have exited it very recently.
64         // Do the damage and renew the timer.
65 #ifdef SVQC
66         Damage (this.owner, this, this, this.dmg, DEATH_SWAMP.m_id, DMG_NOWEP, this.owner.origin, '0 0 0');
67 #endif
68
69         this.nextthink = time + this.swamp_interval;
70 }
71
72 void swamp_touch(entity this, entity toucher)
73 {
74         // If whatever thats touching the swamp is not a player
75         // or if its a dead player, just dont care abt it.
76         if(!IS_PLAYER(toucher) || IS_DEAD(toucher))
77                 return;
78
79         EXACTTRIGGER_TOUCH(this, toucher);
80
81         // Chech if player alredy got a swampslug.
82         if(toucher.in_swamp != 1)
83         {
84                 // If not attach one.
85                 //centerprint(toucher,"Entering swamp!\n");
86                 toucher.swampslug = spawn();
87         #ifdef SVQC
88                 SetResourceAmountExplicit(toucher.swampslug, RESOURCE_HEALTH, 2);
89         #elif defined(CSQC)
90                 toucher.swampslug.health = 2;
91         #endif
92                 setthink(toucher.swampslug, swampslug_think);
93                 toucher.swampslug.nextthink = time;
94                 toucher.swampslug.owner = toucher;
95                 toucher.swampslug.dmg = this.dmg;
96                 toucher.swampslug.swamp_interval = this.swamp_interval;
97                 toucher.swamp_slowdown = this.swamp_slowdown;
98                 toucher.in_swamp = 1;
99                 return;
100         }
101
102         //toucher.in_swamp = 1;
103
104         //Revitalize players swampslug
105 #ifdef SVQC
106         SetResourceAmountExplicit(toucher.swampslug, RESOURCE_HEALTH, 2);
107 #elif defined(CSQC)
108         toucher.swampslug.health = 2;
109 #endif
110 }
111
112 REGISTER_NET_LINKED(ENT_CLIENT_SWAMP)
113
114 #ifdef SVQC
115 float swamp_send(entity this, entity to, float sf)
116 {
117         WriteHeader(MSG_ENTITY, ENT_CLIENT_SWAMP);
118
119         WriteByte(MSG_ENTITY, this.dmg); // can probably get away with using a single byte here
120         WriteByte(MSG_ENTITY, this.swamp_slowdown);
121         WriteByte(MSG_ENTITY, this.swamp_interval);
122
123         trigger_common_write(this, false);
124
125         return true;
126 }
127
128 void swamp_link(entity this)
129 {
130         trigger_link(this, swamp_send);
131 }
132
133 /*QUAKED spawnfunc_trigger_swamp (.5 .5 .5) ?
134 Players gettin into the swamp will
135 get slowd down and damaged
136 */
137 spawnfunc(trigger_swamp)
138 {
139         // Init stuff
140         trigger_init(this);
141         settouch(this, swamp_touch);
142
143         // Setup default keys, if missing
144         if(this.dmg <= 0)
145                 this.dmg = 5;
146         if(this.swamp_interval <= 0)
147                 this.swamp_interval = 1;
148         if(this.swamp_slowdown <= 0)
149                 this.swamp_slowdown = 0.5;
150
151         swamp_link(this);
152 }
153
154 #elif defined(CSQC)
155
156 NET_HANDLE(ENT_CLIENT_SWAMP, bool isnew)
157 {
158         this.dmg = ReadByte();
159         this.swamp_slowdown = ReadByte();
160         this.swamp_interval = ReadByte();
161
162         trigger_common_read(this, false);
163
164         return = true;
165
166         this.classname = "trigger_swamp";
167         this.solid = SOLID_TRIGGER;
168         settouch(this, swamp_touch);
169         this.drawmask = MASK_NORMAL;
170         this.move_time = time;
171         this.entremove = trigger_remove_generic;
172 }
173 #endif