//************************************************************************** //** //** sv_effect.c //** //** Client side effects. //** //** $Header: /HexenWorld/Server/sv_effect.c 39 5/25/98 1:30p Mgummelt $ //** //************************************************************************** // HEADER FILES ------------------------------------------------------------ #include "qwsvdef.h" // MACROS ------------------------------------------------------------------ // TYPES ------------------------------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- static int NewEffectEntity(void); static void FreeEffectEntity(int index); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- extern cvar_t sv_ce_scale; extern cvar_t sv_ce_max_size; // PUBLIC DATA DEFINITIONS ------------------------------------------------- // PRIVATE DATA DEFINITIONS ------------------------------------------------ // CODE -------------------------------------------------------------------- void SV_ClearEffects(void) { memset(sv.Effects,0,sizeof(sv.Effects)); } // All changes need to be in SV_SendEffect(), SV_ParseEffect(), // SV_SaveEffects(), SV_LoadEffects(), CL_ParseEffect() void SV_SendEffect(sizebuf_t *sb, int index) { qboolean DoTest; vec3_t TestO; int TestDistance; int i; if (sv_ce_scale.value > 0) DoTest = true; else DoTest = false; VectorCopy(vec3_origin, TestO); switch(sv.Effects[index].type) { case CE_HWSHEEPINATOR: case CE_HWXBOWSHOOT: VectorCopy(sv.Effects[index].Xbow.origin[5], TestO); TestDistance = 900; break; case CE_SCARABCHAIN: VectorCopy(sv.Effects[index].Chain.origin, TestO); TestDistance = 900; break; case CE_TRIPMINE: VectorCopy(sv.Effects[index].Chain.origin, TestO); // DoTest = false; break; //ACHTUNG!!!!!!! setting DoTest to false here does not insure that effect will be sent to everyone! case CE_TRIPMINESTILL: TestDistance = 10000; DoTest = false; break; case CE_RAIN: TestDistance = 10000; DoTest = false; break; case CE_FOUNTAIN: TestDistance = 10000; DoTest = false; break; case CE_QUAKE: VectorCopy(sv.Effects[index].Quake.origin, TestO); TestDistance = 700; break; case CE_WHITE_SMOKE: case CE_GREEN_SMOKE: case CE_GREY_SMOKE: case CE_RED_SMOKE: case CE_SLOW_WHITE_SMOKE: case CE_TELESMK1: case CE_TELESMK2: case CE_GHOST: case CE_REDCLOUD: case CE_FLAMESTREAM: case CE_ACID_MUZZFL: case CE_FLAMEWALL: case CE_FLAMEWALL2: case CE_ONFIRE: case CE_RIPPLE: VectorCopy(sv.Effects[index].Smoke.origin, TestO); TestDistance = 250; break; case CE_SM_WHITE_FLASH: case CE_YELLOWRED_FLASH: case CE_BLUESPARK: case CE_YELLOWSPARK: case CE_SM_CIRCLE_EXP: case CE_BG_CIRCLE_EXP: case CE_SM_EXPLOSION: case CE_SM_EXPLOSION2: case CE_BG_EXPLOSION: case CE_FLOOR_EXPLOSION: case CE_BLUE_EXPLOSION: case CE_REDSPARK: case CE_GREENSPARK: case CE_ICEHIT: case CE_MEDUSA_HIT: case CE_MEZZO_REFLECT: case CE_FLOOR_EXPLOSION2: case CE_XBOW_EXPLOSION: case CE_NEW_EXPLOSION: case CE_MAGIC_MISSILE_EXPLOSION: case CE_BONE_EXPLOSION: case CE_BLDRN_EXPL: case CE_ACID_HIT: case CE_LBALL_EXPL: case CE_FIREWALL_SMALL: case CE_FIREWALL_MEDIUM: case CE_FIREWALL_LARGE: case CE_ACID_SPLAT: case CE_ACID_EXPL: case CE_FBOOM: case CE_BRN_BOUNCE: case CE_LSHOCK: case CE_BOMB: case CE_FLOOR_EXPLOSION3: VectorCopy(sv.Effects[index].Smoke.origin, TestO); TestDistance = 250; break; case CE_WHITE_FLASH: case CE_BLUE_FLASH: case CE_SM_BLUE_FLASH: case CE_HWSPLITFLASH: case CE_RED_FLASH: VectorCopy(sv.Effects[index].Smoke.origin, TestO); TestDistance = 250; break; case CE_RIDER_DEATH: DoTest = false; break; case CE_TELEPORTERPUFFS: VectorCopy(sv.Effects[index].Teleporter.origin, TestO); TestDistance = 350; break; case CE_TELEPORTERBODY: VectorCopy(sv.Effects[index].Teleporter.origin, TestO); TestDistance = 350; break; case CE_DEATHBUBBLES: if (sv.Effects[index].Bubble.owner < 0 || sv.Effects[index].Bubble.owner >= sv.num_edicts) { return; } VectorCopy(PROG_TO_EDICT(sv.Effects[index].Bubble.owner)->v.origin, TestO); TestDistance = 400; break; case CE_HWDRILLA: case CE_BONESHARD: case CE_BONESHRAPNEL: case CE_HWBONEBALL: case CE_HWRAVENSTAFF: case CE_HWRAVENPOWER: VectorCopy(sv.Effects[index].Missile.origin, TestO); TestDistance = 900; break; case CE_HWMISSILESTAR: case CE_HWEIDOLONSTAR: VectorCopy(sv.Effects[index].Missile.origin, TestO); TestDistance = 600; break; default: // Sys_Error ("SV_SendEffect: bad type"); PR_RunError ("SV_SendEffect: bad type"); break; } MSG_WriteByte (&sv.multicast, svc_start_effect); MSG_WriteByte (&sv.multicast, index); MSG_WriteByte (&sv.multicast, sv.Effects[index].type); switch(sv.Effects[index].type) { case CE_RAIN: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.min_org[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.min_org[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.min_org[2]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.max_org[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.max_org[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.max_org[2]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.e_size[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.e_size[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.e_size[2]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.dir[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.dir[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.dir[2]); MSG_WriteShort(&sv.multicast, sv.Effects[index].Rain.color); MSG_WriteShort(&sv.multicast, sv.Effects[index].Rain.count); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Rain.wait); break; case CE_FOUNTAIN: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Fountain.pos[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Fountain.pos[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Fountain.pos[2]); MSG_WriteAngle(&sv.multicast, sv.Effects[index].Fountain.angle[0]); MSG_WriteAngle(&sv.multicast, sv.Effects[index].Fountain.angle[1]); MSG_WriteAngle(&sv.multicast, sv.Effects[index].Fountain.angle[2]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Fountain.movedir[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Fountain.movedir[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Fountain.movedir[2]); MSG_WriteShort(&sv.multicast, sv.Effects[index].Fountain.color); MSG_WriteByte(&sv.multicast, sv.Effects[index].Fountain.cnt); break; case CE_QUAKE: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Quake.origin[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Quake.origin[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Quake.origin[2]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Quake.radius); break; case CE_WHITE_SMOKE: case CE_GREEN_SMOKE: case CE_GREY_SMOKE: case CE_RED_SMOKE: case CE_SLOW_WHITE_SMOKE: case CE_TELESMK1: case CE_TELESMK2: case CE_GHOST: case CE_REDCLOUD: case CE_FLAMESTREAM: case CE_ACID_MUZZFL: case CE_FLAMEWALL: case CE_FLAMEWALL2: case CE_ONFIRE: case CE_RIPPLE: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[2]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Smoke.velocity[0]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Smoke.velocity[1]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Smoke.velocity[2]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Smoke.framelength); break; case CE_SM_WHITE_FLASH: case CE_YELLOWRED_FLASH: case CE_BLUESPARK: case CE_YELLOWSPARK: case CE_SM_CIRCLE_EXP: case CE_BG_CIRCLE_EXP: case CE_SM_EXPLOSION: case CE_SM_EXPLOSION2: case CE_BG_EXPLOSION: case CE_FLOOR_EXPLOSION: case CE_BLUE_EXPLOSION: case CE_REDSPARK: case CE_GREENSPARK: case CE_ICEHIT: case CE_MEDUSA_HIT: case CE_MEZZO_REFLECT: case CE_FLOOR_EXPLOSION2: case CE_XBOW_EXPLOSION: case CE_NEW_EXPLOSION: case CE_MAGIC_MISSILE_EXPLOSION: case CE_BONE_EXPLOSION: case CE_BLDRN_EXPL: case CE_ACID_HIT: case CE_ACID_SPLAT: case CE_ACID_EXPL: case CE_LBALL_EXPL: case CE_FIREWALL_SMALL: case CE_FIREWALL_MEDIUM: case CE_FIREWALL_LARGE: case CE_FBOOM: case CE_BOMB: case CE_BRN_BOUNCE: case CE_LSHOCK: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[2]); break; case CE_WHITE_FLASH: case CE_BLUE_FLASH: case CE_SM_BLUE_FLASH: case CE_HWSPLITFLASH: case CE_RED_FLASH: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[2]); break; case CE_RIDER_DEATH: MSG_WriteCoord(&sv.multicast, sv.Effects[index].RD.origin[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].RD.origin[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].RD.origin[2]); break; case CE_TELEPORTERPUFFS: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Teleporter.origin[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Teleporter.origin[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Teleporter.origin[2]); break; case CE_TELEPORTERBODY: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Teleporter.origin[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Teleporter.origin[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Teleporter.origin[2]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Teleporter.velocity[0][0]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Teleporter.velocity[0][1]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Teleporter.velocity[0][2]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Teleporter.skinnum); break; case CE_BONESHRAPNEL: case CE_HWBONEBALL: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[2]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.velocity[0]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.velocity[1]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.velocity[2]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.angle[0]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.angle[1]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.angle[2]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.avelocity[0]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.avelocity[1]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.avelocity[2]); break; case CE_BONESHARD: case CE_HWRAVENSTAFF: case CE_HWMISSILESTAR: case CE_HWEIDOLONSTAR: case CE_HWRAVENPOWER: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[2]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.velocity[0]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.velocity[1]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.velocity[2]); break; case CE_HWDRILLA: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[2]); MSG_WriteAngle(&sv.multicast, sv.Effects[index].Missile.angle[0]); MSG_WriteAngle(&sv.multicast, sv.Effects[index].Missile.angle[1]); MSG_WriteShort(&sv.multicast, sv.Effects[index].Missile.speed); break; case CE_DEATHBUBBLES: MSG_WriteShort(&sv.multicast, sv.Effects[index].Bubble.owner); MSG_WriteByte(&sv.multicast, sv.Effects[index].Bubble.offset[0]); MSG_WriteByte(&sv.multicast, sv.Effects[index].Bubble.offset[1]); MSG_WriteByte(&sv.multicast, sv.Effects[index].Bubble.offset[2]); MSG_WriteByte(&sv.multicast, sv.Effects[index].Bubble.count); break; case CE_SCARABCHAIN: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Chain.origin[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Chain.origin[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Chain.origin[2]); MSG_WriteShort(&sv.multicast, sv.Effects[index].Chain.owner+sv.Effects[index].Chain.material); MSG_WriteByte(&sv.multicast, sv.Effects[index].Chain.tag); break; case CE_TRIPMINESTILL: case CE_TRIPMINE: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Chain.origin[0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Chain.origin[1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Chain.origin[2]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Chain.velocity[0]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Chain.velocity[1]); MSG_WriteFloat(&sv.multicast, sv.Effects[index].Chain.velocity[2]); break; case CE_HWSHEEPINATOR: MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[5][0]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[5][1]); MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[5][2]); MSG_WriteAngle(&sv.multicast, sv.Effects[index].Xbow.angle[0]); MSG_WriteAngle(&sv.multicast, sv.Effects[index].Xbow.angle[1]); //now send the guys that have turned MSG_WriteByte(&sv.multicast, sv.Effects[index].Xbow.turnedbolts); MSG_WriteByte(&sv.multicast, sv.Effects[index].Xbow.activebolts); for (i=0;i<5;i++) { if ((1<= MAX_EFFECTS) { PR_RunError ("MAX_EFFECTS reached"); return; } // Con_Printf("Effect #%d\n",index); memset(&sv.Effects[index],0,sizeof(struct EffectT)); sv.Effects[index].type = effect; G_FLOAT(OFS_RETURN) = index; switch(effect) { case CE_RAIN: VectorCopy(G_VECTOR(OFS_PARM1),sv.Effects[index].Rain.min_org); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Rain.max_org); VectorCopy(G_VECTOR(OFS_PARM3),sv.Effects[index].Rain.e_size); VectorCopy(G_VECTOR(OFS_PARM4),sv.Effects[index].Rain.dir); sv.Effects[index].Rain.color = G_FLOAT(OFS_PARM5); sv.Effects[index].Rain.count = G_FLOAT(OFS_PARM6); sv.Effects[index].Rain.wait = G_FLOAT(OFS_PARM7); sv.Effects[index].Rain.next_time = 0; break; case CE_FOUNTAIN: VectorCopy(G_VECTOR(OFS_PARM1),sv.Effects[index].Fountain.pos); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Fountain.angle); VectorCopy(G_VECTOR(OFS_PARM3),sv.Effects[index].Fountain.movedir); sv.Effects[index].Fountain.color = G_FLOAT(OFS_PARM4); sv.Effects[index].Fountain.cnt = G_FLOAT(OFS_PARM5); break; case CE_QUAKE: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Quake.origin); sv.Effects[index].Quake.radius = G_FLOAT(OFS_PARM2); break; case CE_WHITE_SMOKE: case CE_GREEN_SMOKE: case CE_GREY_SMOKE: case CE_RED_SMOKE: case CE_SLOW_WHITE_SMOKE: case CE_TELESMK1: case CE_TELESMK2: case CE_GHOST: case CE_REDCLOUD: case CE_RIPPLE: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Smoke.origin); VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[index].Smoke.velocity); sv.Effects[index].Smoke.framelength = G_FLOAT(OFS_PARM3); sv.Effects[index].expire_time = sv.time + 1; break; case CE_ACID_MUZZFL: case CE_FLAMESTREAM: case CE_FLAMEWALL: case CE_FLAMEWALL2: case CE_ONFIRE: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Smoke.origin); VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[index].Smoke.velocity); sv.Effects[index].Smoke.framelength = 0.05; sv.Effects[index].Smoke.frame = G_FLOAT(OFS_PARM3); sv.Effects[index].expire_time = sv.time + 1; break; case CE_SM_WHITE_FLASH: case CE_YELLOWRED_FLASH: case CE_BLUESPARK: case CE_YELLOWSPARK: case CE_SM_CIRCLE_EXP: case CE_BG_CIRCLE_EXP: case CE_SM_EXPLOSION: case CE_SM_EXPLOSION2: case CE_BG_EXPLOSION: case CE_FLOOR_EXPLOSION: case CE_BLUE_EXPLOSION: case CE_REDSPARK: case CE_GREENSPARK: case CE_ICEHIT: case CE_MEDUSA_HIT: case CE_MEZZO_REFLECT: case CE_FLOOR_EXPLOSION2: case CE_XBOW_EXPLOSION: case CE_NEW_EXPLOSION: case CE_MAGIC_MISSILE_EXPLOSION: case CE_BONE_EXPLOSION: case CE_BLDRN_EXPL: case CE_ACID_HIT: case CE_ACID_SPLAT: case CE_ACID_EXPL: case CE_LBALL_EXPL: case CE_FIREWALL_SMALL: case CE_FIREWALL_MEDIUM: case CE_FIREWALL_LARGE: case CE_FBOOM: case CE_BOMB: case CE_BRN_BOUNCE: case CE_LSHOCK: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Smoke.origin); sv.Effects[index].expire_time = sv.time + 1; break; case CE_WHITE_FLASH: case CE_BLUE_FLASH: case CE_SM_BLUE_FLASH: case CE_HWSPLITFLASH: case CE_RED_FLASH: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Flash.origin); sv.Effects[index].expire_time = sv.time + 1; break; case CE_RIDER_DEATH: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].RD.origin); break; case CE_TELEPORTERPUFFS: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Teleporter.origin); sv.Effects[index].expire_time = sv.time + 1; break; case CE_TELEPORTERBODY: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Teleporter.origin); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Teleporter.velocity[0]); sv.Effects[index].Teleporter.skinnum = G_FLOAT(OFS_PARM3); sv.Effects[index].expire_time = sv.time + 1; break; case CE_BONESHRAPNEL: case CE_HWBONEBALL: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Missile.origin); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Missile.velocity); VectorCopy(G_VECTOR(OFS_PARM3),sv.Effects[index].Missile.angle); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Missile.avelocity); sv.Effects[index].expire_time = sv.time + 10; break; case CE_BONESHARD: case CE_HWRAVENSTAFF: case CE_HWMISSILESTAR: case CE_HWEIDOLONSTAR: case CE_HWRAVENPOWER: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Missile.origin); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Missile.velocity); sv.Effects[index].expire_time = sv.time + 10; break; case CE_DEATHBUBBLES: VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[index].Bubble.offset); sv.Effects[index].Bubble.owner = G_EDICTNUM(OFS_PARM1); sv.Effects[index].Bubble.count = G_FLOAT(OFS_PARM3); sv.Effects[index].expire_time = sv.time + 30; break; case CE_HWDRILLA: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Missile.origin); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Missile.angle); sv.Effects[index].Missile.speed = G_FLOAT(OFS_PARM3); sv.Effects[index].expire_time = sv.time + 10; break; case CE_TRIPMINESTILL: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Chain.origin); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Chain.velocity); sv.Effects[index].expire_time = sv.time + 70; break; case CE_TRIPMINE: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Chain.origin); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Chain.velocity); sv.Effects[index].expire_time = sv.time + 10; break; case CE_SCARABCHAIN: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Chain.origin); sv.Effects[index].Chain.owner = G_EDICTNUM(OFS_PARM2); sv.Effects[index].Chain.material = G_INT(OFS_PARM3); sv.Effects[index].Chain.tag = G_INT(OFS_PARM4); sv.Effects[index].Chain.state = 0; sv.Effects[index].expire_time = sv.time + 15; break; case CE_HWSHEEPINATOR: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[0]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[1]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[2]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[3]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[4]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[5]); VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[index].Xbow.angle); sv.Effects[index].Xbow.bolts = 5; sv.Effects[index].Xbow.activebolts = 31; sv.Effects[index].Xbow.randseed = 0; sv.Effects[index].Xbow.turnedbolts = 0; sv.Effects[index].expire_time = sv.time + 7; break; case CE_HWXBOWSHOOT: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[0]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[1]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[2]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[3]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[4]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[5]); VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[index].Xbow.angle); sv.Effects[index].Xbow.bolts = G_FLOAT(OFS_PARM3); sv.Effects[index].Xbow.randseed = G_FLOAT(OFS_PARM4); sv.Effects[index].Xbow.turnedbolts = 0; if (sv.Effects[index].Xbow.bolts == 3) { sv.Effects[index].Xbow.activebolts = 7; } else { sv.Effects[index].Xbow.activebolts = 31; } sv.Effects[index].expire_time = sv.time + 15; break; default: // Sys_Error ("SV_ParseEffect: bad type"); PR_RunError ("SV_SendEffect: bad type"); } SV_SendEffect(sb,index); } // All changes need to be in SV_SendEffect(), SV_ParseEffect(), // SV_SaveEffects(), SV_LoadEffects(), CL_ParseEffect() void SV_SaveEffects(FILE *FH) { int index,count; for(index=count=0;index= MAX_EFFECTS) { PR_RunError ("MAX_EFFECTS reached"); return; } MSG_WriteByte(sb, index); sv.Effects[index].type = CE_HWRAVENPOWER; VectorCopy(orig, sv.Effects[index].Missile.origin); VectorCopy(vel, sv.Effects[index].Missile.velocity); sv.Effects[index].expire_time = sv.time + 10; MultiEffectIds[count] = index; } break; default: PR_RunError ("SV_ParseMultiEffect: bad type"); } } float SV_GetMultiEffectId(void) { MultiEffectIdCount++; return MultiEffectIds[MultiEffectIdCount-1]; } /* * $Log: /HexenWorld/Server/sv_effect.c $ * * 39 5/25/98 1:30p Mgummelt * * 38 4/23/98 5:17p Mgummelt * Fixes for Siege * * 37 4/20/98 2:03p Rjohnson * Big update * * 36 4/08/98 6:37p Rjohnson * Updated to send effect * * 35 3/26/98 5:01p Mgummelt * Added Mission Pack client effects * * 34 3/25/98 12:45p Rjohnson * Check for death bubbles without an owner * * 33 3/24/98 3:21p Rjohnson * Enable testing for tripmine initial wire * * 32 3/22/98 4:48p Rjohnson * Effects use PVS * * 31 3/21/98 8:10p Rjohnson * Effects through reliable datagram per client now * * 30 3/11/98 9:46p Ssengele * xbolts (& theoretically, setstaff & lambinator) teleport cleanly. * currently cause a spike, which can and will be fixed soon. * server by default only sends the effects close enough to client to * matter to that client. * * 29 3/11/98 3:04p Ssengele * fixed test distance for xbow&lambinator * * 28 3/11/98 3:03p Ssengele * * 27 3/10/98 3:55p Ssengele * expire times more reasonable for effects. * * 26 3/09/98 4:47p Ssengele * started solidifying server tracking of updateable effects: not used * yet; made recoil from daggerdive less extreme than jab; made sure * update message doesn't write over effect info if the type updated is * different from the type already there. * * 25 3/05/98 10:25p Ssengele * fixed a bug with deathbubbles (was crashing when non-client called it) * * 24 3/05/98 9:58p Ssengele * attempt to limit flickering of scarab chains; minimum of 3 b&g mana for * untomed scarab * * 23 3/03/98 8:09p Ssengele * reflection code for xbow bolts and sheepinator; also, a little variance * for where bolts start out, so autoaim doesn't make them clump up quite * as much (variance is consistent between sv & cl) * * 22 3/03/98 4:43p Ssengele * sheepinator uses xbow code now. * * 21 3/03/98 1:58p Ssengele * er, took a break from weapon stuff to move the bubble code over to a * client effect * * 20 3/02/98 6:02p Ssengele * made scarab chains disappear w/o being burden on nettraffic * * 19 3/02/98 4:12p Ssengele * minor improvement for xbow, punchdagger sheep gone away * * 18 3/02/98 2:35p Ssengele * set staff worst-case not bad at all anymore--the drilla is an effect * * 17 3/02/98 12:36p Ssengele * shaved a few bytes from powered up setstaff (moving puffs to client), * have begun working on worst-case unpowered setstaff (explosions are now * tempent * vs effect & sound they were before). unpowered ss still clogs up net * when firing fast--i believe i'll make the whole thing an effect. * * 16 2/28/98 3:26p Ssengele * some work on set staff * * 15 2/27/98 7:12p Ssengele * grrrrrrrr...xbow more optimized than ever (plus chunks, or did i add * those yesterday?), still spiking not-so-pretty (nudges first red line) * occasionally in the worst case scenario. * * 14 2/26/98 3:55p Rmidthun * powered ravenstaff uses multieffect, also moved tempent stuff to be * called from client effects, there is STILL a little red and I'm not * sure if the client effects are always in the correct place, but it * should be close anyway. * * 13 2/26/98 1:34p Rmidthun * working on multiple effects with one net message * * 12 2/25/98 4:01p Rmidthun * ravens are now client effect too, still need to reduce the large * creation spike * * 11 2/24/98 1:41p Ssengele * * 10 2/24/98 11:44a Rmidthun * magic missiles are client effects, the homing function sends updates * * 9 2/23/98 8:04p Ssengele * erg--checking in so's not to hog these files TOO much. cleffect that * handles multiple xbow bolts is IN, but impact is neither consistant nor * in the right spot. * * 8 2/23/98 9:47a Rmidthun * combined small blue flash and split sound for raven staff * * 7 2/20/98 4:45p Rmidthun * moved rest of sounds to client side * * 6 2/20/98 1:15p Ssengele * basic server side of scarab chain in, the effect updating is only half * in, pending the availability of a handful of precious files. * * 5 2/20/98 10:08a Rmidthun * bone shards don't need to send angle or angular vel * * 4 2/19/98 8:07p Ssengele * tripmine client effect in--added access to streams in cl_effect * * 3 2/19/98 7:00p Rmidthun * ravenstaff is almost all client effect, added a "turneffect" builtin to * reduce net traffic further * * 2 2/19/98 4:30p Rmidthun * due to an error in sourcesafe, the previous versions were destroyed. * sorry. * * 1 2/19/98 4:29p Rmidthun * * 8 2/19/98 3:56p Rmidthun * added bone ball * * 7 2/18/98 8:25p Ssengele * xbow client effect (for normal mode) lookin good--but it trades off * significantly less traffic when arrows are in air for a slightly bigger * spike when they're fired. will figure out how to minimize that spike * yet. * * 6 2/18/98 5:37p Ssengele * start at xbow bolt client effect * * 5 2/18/98 3:14p Rmidthun * added load/save for client effect stars * * 4 2/18/98 11:53a Rmidthun * eidolon star (SECOND ATTEMPT) * * 3 2/17/98 6:54p Rmidthun * moving missile stars to client, half done * * 2 2/06/98 4:46p Rjohnson * Server Effects * * 1 2/05/98 5:07p Rjohnson * */