void Inmater_Spawn(ServerEntity_t *eInmater) { Server_PrecacheModel(MODEL_INMATER_BODY); Entity_SetPhysics(eInmater, SOLID_SLIDEBOX, 3.0f, 4.5f); eInmater->Monster.type = MONSTER_INMATER; eInmater->Monster.Frame = Inmater_Think; eInmater->Monster.Pain = Inmater_Pain; Entity_SetKilledFunction(eInmater, Inmater_Die); eInmater->v.takedamage = true; eInmater->v.movetype = MOVETYPE_STEP; eInmater->v.health = INMATER_MAX_HEALTH; eInmater->v.netname = "Inmater"; eInmater->v.frame = 0; eInmater->local.maxhealth = INMATER_MAX_HEALTH; AI_SetState(eInmater, AI_STATE_AWAKE); AI_SetThink(eInmater, AI_THINK_IDLE); Entity_SetModel(eInmater, MODEL_INMATER_BODY); Entity_SetSize(eInmater, -16.0f, -16.0f, -24.0f, 16.0f, 16.0f, 32.0f); Entity_SetOrigin(eInmater, eInmater->v.origin); Entity_DropToFloor(eInmater); }
void Crossbow_Projectile(ServerEntity_t *ent) { // [11/2/2012] Revised and fixed ~hogsy MathVector3f_t mvDirection; ServerEntity_t *eArrow; eArrow = Entity_Spawn(); if(eArrow) { eArrow->local.eOwner = ent; eArrow->v.movetype = MOVETYPE_FLY; eArrow->Physics.iSolid = SOLID_BBOX; Math_MVToVector(Weapon_Aim(ent), mvDirection); Math_VectorScale(mvDirection, 2000.0f, eArrow->v.velocity); Entity_SetModel(eArrow,"models/arrow.md2"); Entity_SetSizeVector(eArrow,g_mvOrigin3f,g_mvOrigin3f); // [25/6/2012] Simplified ~hogsy Math_VectorCopy(ent->v.origin,eArrow->v.origin); eArrow->v.origin[2] += 15.0f; Math_MVToVector(Math_VectorToAngles(ent->v.velocity),ent->v.angles); eArrow->v.TouchFunction = arrow_touch; } }
void Area_NoclipSpawn(ServerEntity_t *area) { area->v.movetype = MOVETYPE_PUSH; area->Physics.solid = SOLID_NOT; Entity_SetModel(area, area->v.model); Entity_SetOrigin(area, area->v.origin); }
// [4/7/2012] Renamed to Discus_SpawnProjectile ~hogsy void Discus_SpawnProjectile(ServerEntity_t *ent,vec3_t org) { ServerEntity_t *eDiscus; MathVector3f_t mvDirection; eDiscus = Entity_Spawn(); eDiscus->v.cClassname = "discus"; eDiscus->v.movetype = MOVETYPE_FLYBOUNCE; eDiscus->Physics.iSolid = SOLID_BBOX; eDiscus->v.effects = EF_MOTION_ROTATE; eDiscus->v.enemy = ent; // [4/8/2012] Updated to use owner instead ~hogsy eDiscus->local.eOwner = ent; eDiscus->local.hit = 0; Math_MVToVector(Weapon_Aim(ent), mvDirection); Math_VectorScale(mvDirection, 700.0f, eDiscus->v.velocity); Math_MVToVector(Math_VectorToAngles(eDiscus->v.velocity), eDiscus->v.angles); eDiscus->v.TouchFunction = Discus_ProjectileTouch; Entity_SetModel(eDiscus, "models/w_daedalus.md2"); Entity_SetSizeVector(eDiscus, g_mvOrigin3f, g_mvOrigin3f); Entity_SetOrigin(eDiscus, org); Sound(ent,CHAN_WEAPON,"weapons/discus/discusthrow.wav",255,ATTN_NORM); }
void Shockwave_SpawnProjectile(ServerEntity_t *ent) { ServerEntity_t *eLaser; Sound(ent,CHAN_WEAPON,"weapons/shockwave/fire.wav",255,ATTN_NORM); ent->v.punchangle[0] -= 10.0f; eLaser = Entity_Spawn(); if(eLaser) { Weapon_Projectile(ent, eLaser, 2000.0f); Math_VectorCopy(ent->v.origin,eLaser->v.origin); Math_MVToVector(plVectorToAngles(eLaser->v.velocity),eLaser->v.angles); eLaser->local.owner = ent; eLaser->v.movetype = MOVETYPE_FLY; eLaser->v.TouchFunction = ShockLaser_Touch; eLaser->v.origin[2] += 25.0f; eLaser->Physics.solid = SOLID_BBOX; Entity_SetModel(eLaser,"models/slaser.md2"); Entity_SetSizeVector(eLaser, pl_origin3f, pl_origin3f); } ent->local.shockwave_ammo--; ent->v.primary_ammo = ent->local.shockwave_ammo; }
void GreekFire_Throw(edict_t *ent) { float *dir; edict_t *greekfire = Entity_Spawn(); greekfire->v.cClassname = "greekfire"; greekfire->v.movetype = MOVETYPE_BOUNCE; greekfire->v.effects = EF_DIMLIGHT; greekfire->Physics.iSolid = SOLID_BBOX; greekfire->local.eOwner = ent; dir = Engine.Aim(ent); greekfire->v.velocity[0] = dir[0]*800; greekfire->v.velocity[1] = dir[1]*800; greekfire->v.velocity[2] = dir[2]*800; Engine.MakeVectors(greekfire->v.v_angle); Entity_SetModel(greekfire,"models/w_greekfire.md2"); Math_MVToVector(Math_VectorToAngles(greekfire->v.velocity),greekfire->v.angles); // [4/7/2012] Simplified ~hogsy Math_VectorCopy(ent->v.origin,greekfire->v.origin); Entity_SetSizeVector(greekfire,mv3Origin,mv3Origin); Engine.LinkEntity(greekfire,false); greekfire->v.TouchFunction = GreekfireTouch; }
void Area_RotateSpawn(ServerEntity_t *area) { if(!area->local.speed) { area->local.speed = 100; } #if 0 // [26/7/2012] Check our spawn flags ~hogsy if(area->local.style == STYLE_ROTATE_DOOR) { if(area->v.spawnflags & SPAWNFLAG_ROTATE_REVERSE) { } if(area->v.spawnflags & SPAWNFLAG_ROTATE_X) area->v.movedir[0] = 1.0f; else if(area->v.spawnflags & SPAWNFLAG_ROTATE_Y) area->v.movedir[1] = 1.0f; else area->v.movedir[2] = 1.0f; Math_VectorCopy(area->v.angles,area->local.pos1); area->local.pos2[0] = area->local.pos1[0]+area->v.movedir[0]*area->local.distance; area->v.TouchFunction = Area_RotateTouch; area->local.dMoveFinished = 0; } else #endif { if(area->v.spawnflags & SPAWNFLAG_ROTATE_REVERSE) { area->local.speed *= -1; } if(area->v.spawnflags & SPAWNFLAG_ROTATE_X) { area->v.avelocity.x = area->local.speed; } if(area->v.spawnflags & SPAWNFLAG_ROTATE_Y) { area->v.avelocity.y = area->local.speed; } if(area->v.spawnflags & SPAWNFLAG_ROTATE_Z) { area->v.avelocity.z = area->local.speed; } } Entity_SetBlockedFunction(area, Area_RotateBlocked); area->v.movetype = MOVETYPE_PUSH; area->v.think = Area_RotateThink; area->v.nextthink = Server.time + 1000000000.0; // TODO: This is a hack. A dirty filthy hack. Curse it and its family! area->Physics.solid = SOLID_BSP; Entity_SetModel(area,area->v.model); Entity_SetSizeVector(area,area->v.mins,area->v.maxs); Entity_SetOrigin(area,area->v.origin); }
void Area_ButtonSpawn(ServerEntity_t *eArea) { float fDist; PLVector3D vMoveDir; if(!eArea->v.spawnflags) eArea->v.spawnflags = 0; if(eArea->local.cSoundStart) Server_PrecacheSound(eArea->local.cSoundStart); if (eArea->local.sound_stop) Server_PrecacheSound(eArea->local.sound_stop); if(eArea->local.cSoundMoving) Server_PrecacheSound(eArea->local.cSoundMoving); if(eArea->local.cSoundReturn) Server_PrecacheSound(eArea->local.cSoundReturn); eArea->v.movetype = MOVETYPE_PUSH; eArea->Physics.solid = SOLID_BSP; // [18/5/2013] Changed to use ! check instead since it's safer here ~hogsy if(eArea->local.lip == 0) { eArea->local.lip = 4; } eArea->local.value = 0; eArea->local.flags = STATE_BOTTOM; Entity_SetModel(eArea,eArea->v.model); Entity_SetOrigin(eArea,eArea->v.origin); Entity_SetSizeVector(eArea,eArea->v.mins,eArea->v.maxs); eArea->local.pos1 = eArea->v.origin; Area_SetMoveDirection(eArea->v.angles,eArea->v.movedir); vMoveDir.x = std::fabs(eArea->v.movedir.x); vMoveDir.y = std::fabs(eArea->v.movedir.y); vMoveDir.z = std::fabs(eArea->v.movedir.z); fDist = vMoveDir.x*eArea->v.size.x+ vMoveDir.y*eArea->v.size.y+ vMoveDir.z*eArea->v.size.z- eArea->local.lip; Math_VectorMake(eArea->local.pos1,fDist,eArea->v.movedir,&eArea->local.pos2); if(eArea->v.spawnflags != 32) { // Toggle eArea->v.TouchFunction = Area_ButtonTouch; } if (eArea->local.damage) { Entity_SetBlockedFunction(eArea, Area_ButtonBlocked); } eArea->v.use = Area_ButtonUse; }
void Area_KillSpawn(ServerEntity_t *area) { area->Physics.solid = SOLID_TRIGGER; Entity_SetModel(area, area->v.model); Entity_SetOrigin(area, area->v.origin); Entity_SetTouchFunction(area, Area_KillTouch); area->v.model = 0; }
void Area_PlatformSpawn(ServerEntity_t *area) { if(!area->v.spawnflags) { area->v.spawnflags = 0; } if(area->local.cSoundStart) { Server_PrecacheSound(area->local.cSoundStart); } if (area->local.sound_stop) { Server_PrecacheSound(area->local.sound_stop); } if(area->local.cSoundMoving) { Server_PrecacheSound(area->local.cSoundMoving); } if(area->local.cSoundReturn) { Server_PrecacheSound(area->local.cSoundReturn); } area->v.movetype = MOVETYPE_PUSH; area->Physics.solid = SOLID_BSP; if(area->local.count == 0) { area->local.count = 100; } if(area->local.wait == 0) { area->local.wait = 3; } if(area->local.damage == 0) { area->local.damage = 20; } area->local.value = 0; area->local.flags = STATE_BOTTOM; Entity_SetModel(area,area->v.model); Entity_SetOrigin(area,area->v.origin); Entity_SetSizeVector(area,area->v.mins,area->v.maxs); area->local.pos1 = area->v.origin; Area_SetMoveDirection(area->v.angles, area->v.movedir); float dist = (float)area->local.count; Math_VectorMake(area->local.pos1, dist, area->v.movedir, &area->local.pos2); if(area->v.spawnflags != 32) { // Toggle area->v.TouchFunction = Area_PlatformTouch; } if (area->local.damage) { Entity_SetBlockedFunction(area, Area_PlatformBlocked); } area->v.use = Area_PlatformUse; }
void Area_ClimbSpawn(ServerEntity_t *area) { Area_SetMoveDirection(area->v.angles, area->v.movedir); area->v.TouchFunction = Area_ClimbTouch; area->Physics.solid = SOLID_TRIGGER; Entity_SetModel(area,area->v.model); Entity_SetOrigin(area,area->v.origin); area->v.model = 0; }
// [4/8/2012] Renamed to SideWinder_SpawnMissle ~hogsy void SideWinder_SpawnMissle(edict_t *ent,float fSpeed,float ox) { // [26/2/2012] Revised and fixed ~hogsy vec3_t vOrg; edict_t *eMissile = Entity_Spawn(); /* TODO: Spawn a flare at our position too ~hogsy */ eMissile->v.cClassname = "sidewindermissile"; eMissile->v.movetype = MOVETYPE_FLYMISSILE; eMissile->v.effects = EF_PARTICLE_SMOKE|EF_DIMLIGHT; eMissile->Physics.iSolid = SOLID_BBOX; eMissile->Physics.eIgnore = ent; eMissile->local.speed = SIDEWINDER_MAXSPEED; eMissile->local.eOwner = ent; eMissile->local.count = 0; // [4/8/2012] Change our speed depending on what contents we're within ~hogsy eMissile->local.speed = fSpeed; Math_VectorScale(Engine.Aim(ent),eMissile->local.speed,eMissile->v.velocity); Math_AngleVectors(ent->v.v_angle, // [4/8/2012] Set up our angle vectors ~hogsy eMissile->v.vForward, eMissile->local.vRight, eMissile->local.vUp); Math_VectorCopy(ent->v.v_angle,eMissile->v.angles); Entity_SetModel(eMissile,"models/sidewinder_missile.md2"); Math_VectorCopy(ent->v.origin,vOrg); vOrg[0] += eMissile->v.vForward[0]*8+eMissile->local.vRight[0]*ox; vOrg[1] += eMissile->v.vForward[1]*8+eMissile->local.vRight[1]*ox; vOrg[2] += eMissile->v.vForward[2]*24; Entity_SetSizeVector(eMissile,mv3Origin,mv3Origin); Entity_SetOrigin(eMissile,vOrg); // [4/8/2012] Time at which we'll be removed if nothing hit ~hogsy eMissile->local.fSpawnDelay = (float)(Server.dTime+8.0); eMissile->v.TouchFunction = SideWinder_MissileExplode; eMissile->v.dNextThink = Server.dTime+0.05; eMissile->v.think = SideWinder_Think; // [4/8/2012] Moved so we do this last! ~hogsy Engine.LinkEntity(eMissile,false); }
// Just for the compiler ~eukara void Area_DetailSpawn(ServerEntity_t *area) { if(!area->v.model) { g_engine->Con_Warning("Area entity with no model!\n"); Entity_Remove(area); return; } Entity_SetModel(area,area->v.model); Entity_SetOrigin(area,area->v.origin); }
void Area_PushSpawn(ServerEntity_t *area) { if(!area->local.speed) area->local.speed = 500.0f; Area_SetMoveDirection(area->v.angles, area->v.movedir); area->v.TouchFunction = Area_PushTouch; area->Physics.solid = SOLID_TRIGGER; Entity_SetModel(area,area->v.model); Entity_SetOrigin(area,area->v.origin); Entity_SetSizeVector(area,area->v.mins,area->v.maxs); area->v.model = 0; }
void Point_DecorationSpawn(ServerEntity_t *eDecoration) { if (eDecoration->v.model[0] == ' ') { Entity_Remove(eDecoration); return; } Server_PrecacheModel(eDecoration->v.model); Entity_SetModel(eDecoration,eDecoration->v.model); if(eDecoration->v.spawnflags & DECORATION_DROPTOFLOOR) Entity_DropToFloor(eDecoration); }
void Area_WallUse(ServerEntity_t *area) { if(area->Physics.solid == SOLID_BSP) { area->local.oldmodel = area->v.model; area->local.value = 0; area->Physics.solid = SOLID_NOT; area->v.model = 0; return; } area->Physics.solid = SOLID_BSP; area->local.value = 1; Entity_SetModel(area,area->local.oldmodel); }
void C4Vizatergo_PrimaryAttack(ServerEntity_t *eOwner) { MathVector3f_t vOrigin; MathVector3f_t mvDirection; ServerEntity_t *c4ball = Entity_Spawn(); Sound(eOwner,CHAN_AUTO,"weapons/c4/c4fire.wav",255,ATTN_NORM); Sound(eOwner,CHAN_AUTO,"weapons/c4/c4cock.wav",255,ATTN_NORM); Weapon_Animate(eOwner,C4Animation_Fire1); Weapon_ViewPunch(eOwner, 7, true); eOwner->v.iPrimaryAmmo = eOwner->local.iC4Ammo -= 1; c4ball->v.cClassname = "c4ball"; c4ball->v.movetype = MOVETYPE_BOUNCE; c4ball->local.style = AMMO_C4BOMBS; // Cleaner way to tell if this can explode or not :V ~hogsy c4ball->local.iC4Ammo = 1; // [11/8/2013] Since style is used for other shit too LAWL ~hogsy c4ball->local.eOwner = eOwner; // Set the physical properties. c4ball->Physics.iSolid = SOLID_BBOX; c4ball->Physics.fMass = 0.9f; c4ball->Physics.eIgnore = eOwner; c4ball->Physics.fGravity = SERVER_GRAVITY; Math_MVToVector(Weapon_Aim(eOwner), mvDirection); Math_VectorScale(mvDirection, C4VIZATERGO_MAX_RANGE, c4ball->v.velocity); c4ball->v.velocity[pY] += 20.0f; Math_MVToVector(Math_VectorToAngles(c4ball->v.velocity),c4ball->v.angles); Math_VectorCopy(eOwner->v.origin,vOrigin); c4ball->v.TouchFunction = C4Vizatergo_C4BallTouch; c4ball->v.think = C4Vizatergo_Think; c4ball->v.dNextThink = Server.dTime + 2.5; Entity_SetModel(c4ball,"models/c4ammo.md2"); Entity_SetSizeVector(c4ball,g_mvOrigin3f,g_mvOrigin3f); Entity_SetOrigin(c4ball,vOrigin); if(eOwner->local.attackb_finished > Server.dTime) // No attack boost... eOwner->local.dAttackFinished = Server.dTime+0.6; else eOwner->local.dAttackFinished = Server.dTime+1.2; }
void Area_PushableSpawn(ServerEntity_t *area) { // TODO: If designed to be breakable, make breakable? ~eukara /* if (area->v.health) { Area_BreakableSpawn(area); } */ //area->Physics.fGravity = cv_server_gravity.value; area->v.angles = 0; area->Physics.solid = SOLID_SLIDEBOX; area->v.movetype = MOVETYPE_STEP; Entity_SetModel(area,area->v.model); Entity_SetOrigin(area,area->v.origin); Entity_SetSizeVector(area,area->v.mins,area->v.maxs); area->v.TouchFunction = Area_PushableTouch; area->v.think = Area_PushableThink; }
void Area_TriggerSpawn(ServerEntity_t *area) { if(!area->v.targetname) { g_engine->Con_Warning("'targetname' not set for trigger! (%i %i %i)\n", (int)area->v.origin.x, (int)area->v.origin.y, (int)area->v.origin.z); return; } area->v.TouchFunction = Area_TriggerTouch; area->Physics.solid = SOLID_TRIGGER; Entity_SetModel(area,area->v.model); Entity_SetOrigin(area,area->v.origin); area->v.model = 0; }
void Area_ChangeLevel(ServerEntity_t *area) { if(!area->v.targetname) { g_engine->Con_Warning("No targetname set for area_changelevel! (%i %i %i)\n", (int)area->v.origin.x, (int)area->v.origin.y, (int)area->v.origin.z); return; } area->v.TouchFunction = Area_ChangeLevelTouch; area->Physics.solid = SOLID_TRIGGER; Entity_SetModel(area,area->v.model); Entity_SetOrigin(area,area->v.origin); area->v.model = 0; }
void Area_WallSpawn(ServerEntity_t *area) { if(!area->v.model) { g_engine->Con_Warning("Area entity with no model!\n"); Entity_Remove(area); return; } if(area->v.name) { area->v.use = Area_WallUse; } area->v.movetype = MOVETYPE_PUSH; area->local.value = 1; Entity_SetModel(area,area->v.model); Entity_SetOrigin(area,area->v.origin); }
void Area_CreateGib(ServerEntity_t *area, const char *model) { ServerEntity_t *gib = Entity_Spawn(); if (gib) { gib->v.classname = "entity_gib"; gib->v.movetype = MOVETYPE_BOUNCE; gib->v.TouchFunction = Area_BreakableBounce; gib->v.think = Entity_Remove; gib->v.nextthink = Server.time + 20; gib->v.takedamage = false; gib->Physics.solid = SOLID_TRIGGER; gib->local.style = area->local.style; gib->v.velocity.x = gib->v.avelocity.x = (float)(rand() % 5 * area->v.health * 5); gib->v.velocity.y = gib->v.avelocity.y = (float)(rand() % 5 * area->v.health * 5); gib->v.velocity.z = gib->v.avelocity.z = (float)(rand() % 5 * area->v.health * 5); Entity_SetModel(gib, model); Entity_SetOrigin(gib, area->v.oldorigin); Entity_SetSizeVector(gib, PLVector3D(), PLVector3D()); } }
void GreekFire_Throw(ServerEntity_t *ent) { ServerEntity_t *greekfire = Entity_Spawn(); greekfire->v.cClassname = "greekfire"; greekfire->v.movetype = MOVETYPE_BOUNCE; greekfire->v.effects = EF_DIMLIGHT; greekfire->Physics.iSolid = SOLID_BBOX; greekfire->local.eOwner = ent; Weapon_Projectile(ent,greekfire,800.0f); Entity_SetModel(greekfire,"models/w_greekfire.md2"); Math_MVToVector(Math_VectorToAngles(greekfire->v.velocity),greekfire->v.angles); // Use SetOrigin since it automatically links. Entity_SetOrigin(greekfire, ent->v.origin); Entity_SetSizeVector(greekfire,g_mvOrigin3f,g_mvOrigin3f); greekfire->v.TouchFunction = GreekfireTouch; }
/* Uses both primary burst and mega burst! */ void IonRifle_PrimaryAttack(edict_t *eOwner) { switch(eOwner->local.iFireMode) { case 1: Weapon_Animate(eOwner,efIonRifleBlastFire); eOwner->v.punchangle[0] -= (float)(((rand()%10)+5)); eOwner->local.ionblaster_ammo -= 5; { edict_t *eIonBall = Entity_Spawn(); if(eIonBall) { vec3_t vOrigin; eIonBall->v.cClassname = "ionball"; eIonBall->v.movetype = MOVETYPE_FLY; eIonBall->v.effects = EF_LIGHT_GREEN; eIonBall->v.TouchFunction = IonRifle_IonBallTouch; eIonBall->Model.fScale = 2.0f; eIonBall->Physics.iSolid = SOLID_BBOX; eIonBall->Physics.eIgnore = eOwner; eIonBall->local.eOwner = eOwner; eIonBall->local.style = 1; // [29/1/2014] Preserve our firemode ~hogsy Math_VectorCopy(eOwner->v.origin,vOrigin); vOrigin[2] += 25.0f; Entity_SetModel(eIonBall,"models/ionball.md2"); Entity_SetSizeVector(eIonBall,mv3Origin,mv3Origin); Entity_SetOrigin(eIonBall,vOrigin); { vec_t *vAim = Engine.Aim(eOwner); Math_VectorScale(vAim,IONRIFLE_MAX_RANGE,eIonBall->v.velocity); Math_VectorCopy(vAim,eIonBall->v.angles); } Engine.LinkEntity(eIonBall,false); } } if(eOwner->local.attackb_finished > Server.dTime) eOwner->local.dAttackFinished = Server.dTime+0.10; else eOwner->local.dAttackFinished = Server.dTime+0.5; break; default: // Simple bursts Sound(eOwner,CHAN_AUTO,"weapons/laser.wav",255,ATTN_NORM); switch(eOwner->local.iBarrelCount) { case 0: Weapon_Animate(eOwner,efIonRiflePulseFireA); break; case 1: Weapon_Animate(eOwner,efIonRiflePulseFireB); break; case 2: Weapon_Animate(eOwner,efIonRiflePulseFireC); break; case 3: Weapon_Animate(eOwner,efIonRiflePulseFireD); break; case 4: Weapon_Animate(eOwner,efIonRiflePulseFireE); } // [25/9/2013] Punch the view back ~hogsy eOwner->v.punchangle[0] -= (float)(((rand()%5)+1)/10.0f); eOwner->local.ionblaster_ammo--; // [29/1/2014] Let us cycle through each barrel on an individual basis ~hogsy eOwner->local.iBarrelCount++; if(eOwner->local.iBarrelCount >= 4) eOwner->local.iBarrelCount = 0; { edict_t *eIonBall = Entity_Spawn(); if(eIonBall) { vec3_t vOrigin; eIonBall->v.cClassname = "ionball"; eIonBall->v.movetype = MOVETYPE_FLY; eIonBall->v.effects = EF_LIGHT_GREEN; eIonBall->v.TouchFunction = IonRifle_IonBallTouch; eIonBall->Model.fScale = 0.3f; eIonBall->Physics.iSolid = SOLID_BBOX; eIonBall->Physics.eIgnore = eOwner; eIonBall->local.eOwner = eOwner; eIonBall->local.style = 0; // [29/1/2014] Preserve our firemode ~hogsy Math_VectorCopy(eOwner->v.origin,vOrigin); vOrigin[2] += 25.0f; Entity_SetModel(eIonBall,"models/ionball.md2"); Entity_SetSizeVector(eIonBall,mv3Origin,mv3Origin); Entity_SetOrigin(eIonBall,vOrigin); { vec_t *vAim = Engine.Aim(eOwner); Math_VectorScale(vAim,IONRIFLE_MAX_RANGE,eIonBall->v.velocity); Math_VectorCopy(vAim,eIonBall->v.avelocity); } Engine.LinkEntity(eIonBall,false); } } if(eOwner->local.attackb_finished > Server.dTime) eOwner->local.dAttackFinished = Server.dTime+0.5; else eOwner->local.dAttackFinished = Server.dTime+0.3; } // [17/11/2013] Update ammo counts... ~hogsy eOwner->v.iPrimaryAmmo = eOwner->local.ionblaster_ammo; }
/* style 0 Mikiko 1 Superfly */ void Bot_Spawn(edict_t *eBot) { int iSpawnType; edict_t *eSpawnPoint; // [20/1/2013] Don't spawn bots unless it's allowed by admin ~hogsy if(!cvServerBots.value) return; Math_VectorClear(eBot->v.velocity); // [29/7/2012] Names are now set here, the otherway was dumb ~hogsy switch(eBot->local.style) { case BOT_DEFAULT: iSpawnType = INFO_PLAYER_DEATHMATCH; eBot->v.model = cvServerPlayerModel.string; eBot->v.netname = BotNames[(rand()%pARRAYELEMENTS(BotNames))]; eBot->monster.iType = MONSTER_PLAYER; break; #ifdef OPENKATANA case BOT_MIKIKO: iSpawnType = INFO_PLAYER_MIKIKO; Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/mikiko.md2"); eBot->v.model = "models/mikiko.md2"; eBot->v.netname = "Mikiko Ebihara"; eBot->monster.iType = MONSTER_MIKIKO; break; case BOT_SUPERFLY: iSpawnType = INFO_PLAYER_SUPERFLY; Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/sprfly.md2"); Engine.Server_PrecacheResource(RESOURCE_SOUND,"player/superfly/superflydeath1.wav"); Engine.Server_PrecacheResource(RESOURCE_SOUND,"player/superfly/superflydeath2.wav"); Engine.Server_PrecacheResource(RESOURCE_SOUND,"player/superfly/superflydeath3.wav"); Engine.Server_PrecacheResource(RESOURCE_SOUND,"player/superfly/superflydeath4.wav"); eBot->v.model = "models/sprfly.md2"; eBot->v.netname = "Superfly Johnson"; eBot->monster.iType = MONSTER_SUPERFLY; break; #endif default: // [22/3/2013] Removed multiplayer support ~hogsy Engine.Con_Warning("Attempted to spawn unknown bot type! (%i) (%i %i %i)\n", eBot->local.style, (int)eBot->v.origin[0], (int)eBot->v.origin[1], (int)eBot->v.origin[2]); ENTITY_REMOVE(eBot); } eBot->v.cClassname = "bot"; eBot->v.iHealth = 100; eBot->v.iMaxHealth = (int)cvServerMaxHealth.value; eBot->v.movetype = MOVETYPE_STEP; eBot->v.bTakeDamage = true; eBot->Physics.iSolid = SOLID_SLIDEBOX; eBot->Physics.fGravity = SERVER_GRAVITY; eBot->Physics.fMass = 1.4f; eBot->Physics.fFriction = 4.0f; eBot->local.bBleed = true; eBot->monster.Think = Bot_Think; // Mikiko and Superfly are set manually to avoid issues... ~hogsy if(eBot->local.style == BOT_DEFAULT) { // [16/7/2012] Must be set after teams are set up ~hogsy eSpawnPoint = Entity_SpawnPoint(eBot,iSpawnType); if(!eSpawnPoint) { Engine.Con_Warning("%s failed to find spawnpoint!\n",eBot->v.netname); ENTITY_REMOVE(eBot); } Entity_SetOrigin(eBot,eSpawnPoint->v.origin); SetAngle(eBot,eSpawnPoint->v.angles); } // [15/7/2012] Set the initial state to awake ~hogsy eBot->monster.think_die = Bot_Die; eBot->monster.think_pain = Bot_Pain; eBot->monster.Think = Bot_Think; Entity_SetModel(eBot,eBot->v.model); Entity_SetSize(eBot,-16.0f,-16.0f,-24.0f,16.0f,16.0f,32.0f); Monster_SetState(eBot,STATE_AWAKE); Monster_SetThink(eBot,THINK_IDLE); // [6/8/2012] Make sure we're not in the air ~hogsy DropToFloor(eBot); }
void Area_BreakableSpawn(ServerEntity_t *area) { if (area->v.health <= 0) { area->v.health = 1; } switch (area->local.style) { case BREAKABLE_GLASS: Server_PrecacheSound( PHYSICS_SOUND_GLASS0); Server_PrecacheSound( PHYSICS_SOUND_GLASS1); Server_PrecacheSound( PHYSICS_SOUND_GLASS2); Server_PrecacheModel(PHYSICS_MODEL_GLASS0); Server_PrecacheModel(PHYSICS_MODEL_GLASS1); Server_PrecacheModel(PHYSICS_MODEL_GLASS2); break; case BREAKABLE_WOOD: Server_PrecacheSound( PHYSICS_SOUND_WOOD0); Server_PrecacheSound( PHYSICS_SOUND_WOOD1); Server_PrecacheSound( PHYSICS_SOUND_WOOD2); Server_PrecacheModel(PHYSICS_MODEL_WOOD0); Server_PrecacheModel(PHYSICS_MODEL_WOOD1); Server_PrecacheModel(PHYSICS_MODEL_WOOD2); break; case BREAKABLE_ROCK: Server_PrecacheSound( PHYSICS_SOUND_ROCK0); Server_PrecacheSound( PHYSICS_SOUND_ROCK1); Server_PrecacheSound( PHYSICS_SOUND_ROCK2); Server_PrecacheModel(PHYSICS_MODEL_ROCK0); Server_PrecacheModel(PHYSICS_MODEL_ROCK1); Server_PrecacheModel(PHYSICS_MODEL_ROCK2); break; case BREAKABLE_METAL: Server_PrecacheSound( PHYSICS_SOUND_METAL0); Server_PrecacheSound( PHYSICS_SOUND_METAL1); Server_PrecacheSound( PHYSICS_SOUND_METAL2); Server_PrecacheModel(PHYSICS_MODEL_METAL0); Server_PrecacheModel(PHYSICS_MODEL_METAL1); Server_PrecacheModel(PHYSICS_MODEL_METAL2); break; default: g_engine->Con_Warning("area_breakable: Unknown style\n"); } // If we've been given a name, then set our use function. if (area->v.name) { area->v.use = Area_BreakableUse; } area->Physics.solid = SOLID_BSP; area->v.movetype = MOVETYPE_PUSH; area->v.takedamage = true; area->local.bleed = false; Entity_SetKilledFunction(area, Area_BreakableDie); Entity_SetModel(area, area->v.model); Entity_SetOrigin(area, area->v.origin); Entity_SetSizeVector(area, area->v.mins, area->v.maxs); area->v.oldorigin.x = (area->v.mins.x + area->v.maxs.x) * 0.5f; area->v.oldorigin.y = (area->v.mins.y + area->v.maxs.y) * 0.5f; area->v.oldorigin.z = (area->v.mins.z + area->v.maxs.z) * 0.5f; }
/* style 0 Mikiko 1 Superfly */ void Bot_Spawn(ServerEntity_t *eBot) { int iSpawnType; ServerEntity_t *eSpawnPoint; // Don't spawn bots unless it's allowed by admin. if(!cvServerBots.value) return; plClearVector3D(&eBot->v.velocity); switch(eBot->local.style) { case BOT_DEFAULT: iSpawnType = INFO_PLAYER_DEATHMATCH; eBot->v.model = cvServerPlayerModel.string; strncpy(eBot->v.netname, BotNames[(rand() % plArrayElements(BotNames))], 64); eBot->Monster.type = MONSTER_PLAYER; break; #ifdef GAME_OPENKATANA case BOT_COMPANION: iSpawnType = INFO_PLAYER_SUPERFLY; Server_PrecacheModel("models/sprfly.md2"); // TODO: Placeholder! Server_PrecacheSound("player/superfly/superflydeath1.wav"); // TODO: Placeholder! Server_PrecacheSound("player/superfly/superflydeath2.wav"); // TODO: Placeholder! Server_PrecacheSound("player/superfly/superflydeath3.wav"); // TODO: Placeholder! Server_PrecacheSound("player/superfly/superflydeath4.wav"); // TODO: Placeholder! eBot->v.model = "models/sprfly.md2"; // TODO: Placeholder! eBot->v.netname = "Companion Bot"; // TODO: give a proper name?? eBot->Monster.type = MONSTER_SUPERFLY; break; #endif default: Engine.Con_Warning("Attempted to spawn unknown bot type! (%i) (%i %i %i)\n", eBot->local.style, (int)eBot->v.origin.x, (int)eBot->v.origin.y, (int)eBot->v.origin.z); Entity_Remove(eBot); return; } eBot->v.classname = "bot"; eBot->v.health = 100; eBot->local.maxhealth = cvServerMaxHealth.iValue; eBot->v.movetype = MOVETYPE_STEP; eBot->v.takedamage = true; Entity_SetPhysics(eBot, SOLID_SLIDEBOX, 1.4f, 4.0f); eBot->local.bleed = true; eBot->Monster.Frame = Bot_Frame; eBot->Monster.Pain = Bot_Pain; // Default bots are purely for MP, so they spawn at player spawns. if(eBot->local.style == BOT_DEFAULT) { // Must be set after teams are set up. eSpawnPoint = Player_GetSpawnEntity(eBot, iSpawnType); if(!eSpawnPoint) { Engine.Con_Warning("%s failed to find spawnpoint!\n",eBot->v.netname); Entity_Remove(eBot); return; } Entity_SetOrigin(eBot,eSpawnPoint->v.origin); SetAngle(eBot,eSpawnPoint->v.angles); } Entity_SetKilledFunction(eBot, Bot_Die); eBot->Monster.Pain = Bot_Pain; eBot->Monster.Frame = Bot_Frame; Entity_SetModel(eBot,eBot->v.model); Entity_SetSize(eBot,-16.0f,-16.0f,-24.0f,16.0f,16.0f,32.0f); AI_SetState(eBot, AI_STATE_AWAKE); AI_SetThink(eBot, AI_THINK_IDLE); // Make sure we're not in the air. Entity_DropToFloor(eBot); }
void Point_PropSpawn(ServerEntity_t *eEntity) { if(!eEntity->v.model) Entity_Remove(eEntity); eEntity->v.iHealth = 10; if(eEntity->v.iHealth) { switch(eEntity->local.style) { case BREAKABLE_GLASS: Server_PrecacheSound(PHYSICS_SOUND_GLASS0); Server_PrecacheSound(PHYSICS_SOUND_GLASS1); Server_PrecacheSound(PHYSICS_SOUND_GLASS2); Server_PrecacheModel(PHYSICS_MODEL_GLASS0); Server_PrecacheModel(PHYSICS_MODEL_GLASS1); Server_PrecacheModel(PHYSICS_MODEL_GLASS2); break; case BREAKABLE_WOOD: Server_PrecacheSound(PHYSICS_SOUND_WOOD0); Server_PrecacheSound(PHYSICS_SOUND_WOOD1); Server_PrecacheSound(PHYSICS_SOUND_WOOD2); Server_PrecacheModel(PHYSICS_MODEL_WOOD0); Server_PrecacheModel(PHYSICS_MODEL_WOOD1); Server_PrecacheModel(PHYSICS_MODEL_WOOD2); break; case BREAKABLE_ROCK: Server_PrecacheSound(PHYSICS_SOUND_ROCK0); Server_PrecacheSound(PHYSICS_SOUND_ROCK1); Server_PrecacheSound(PHYSICS_SOUND_ROCK2); Server_PrecacheModel("models/gibs/rock_gibs1.md2"); Server_PrecacheModel("models/gibs/rock_gibs2.md2"); Server_PrecacheModel("models/gibs/rock_gibs3.md2"); break; case BREAKABLE_METAL: Server_PrecacheSound(PHYSICS_SOUND_METAL0); Server_PrecacheSound(PHYSICS_SOUND_METAL1); Server_PrecacheSound(PHYSICS_SOUND_METAL2); Server_PrecacheModel(PHYSICS_MODEL_METAL0); Server_PrecacheModel(PHYSICS_MODEL_METAL1); Server_PrecacheModel(PHYSICS_MODEL_METAL2); break; default: Engine.Con_Warning("Prop with unknown style! (%i)\n",eEntity->local.style); } eEntity->v.bTakeDamage = true; eEntity->local.bBleed = false; Entity_SetKilledFunction(eEntity, Area_BreakableDie); } Server_PrecacheModel(eEntity->v.model); eEntity->v.movetype = MOVETYPE_BOUNCE; eEntity->v.TouchFunction = Point_PropTouch; eEntity->Physics.iSolid = SOLID_BBOX; eEntity->Physics.fGravity = cvServerGravity.value; eEntity->Physics.fMass = 0.5f; Entity_SetModel(eEntity,eEntity->v.model); Entity_SetOrigin(eEntity,eEntity->v.origin); Entity_SetSize(eEntity,-16.0f,-16.0f,-24.0f,16.0f,16.0f,32.0f); }
void Area_DoorSpawn(ServerEntity_t *door) { PLVector3D movedir; if (door->local.cSoundStart) { Server_PrecacheSound(door->local.cSoundStart); } if (door->local.sound_stop) { Server_PrecacheSound(door->local.sound_stop); } if (door->local.cSoundMoving) { Server_PrecacheSound(door->local.cSoundMoving); } if (door->local.cSoundReturn) { Server_PrecacheSound(door->local.cSoundReturn); } door->v.movetype = MOVETYPE_PUSH; Entity_SetPhysics(door, SOLID_BSP, 1.0f, 1.0f); Entity_SetModel(door, door->v.model); Entity_SetOrigin(door, door->v.origin); Entity_SetSizeVector(door, door->v.mins, door->v.maxs); if (door->local.lip == 0) { door->local.lip = 4; } door->local.pos1 = door->v.origin; Area_SetMoveDirection(door->v.angles, door->v.movedir); movedir.x = std::fabs(door->v.movedir.x); movedir.y = std::fabs(door->v.movedir.y); movedir.z = std::fabs(door->v.movedir.z); float movedist = movedir.x * door->v.size.x + movedir.y * door->v.size.y + movedir.z * door->v.size.z - door->local.lip; #if 0 Math_VectorMake(door->local.pos1, movedist, door->v.movedir, door->local.pos2); #else door->local.pos2 = door->local.pos1 + (door->v.movedir * movedist); #endif door->local.flags = STATE_BOTTOM; // Set the spawn flags up. if (door->v.spawnflags & DOOR_FLAG_TRIGGERUSE) { door->v.use = Area_DoorUse; } if (door->v.spawnflags & DOOR_FLAG_TRIGGERTOUCH) { door->v.TouchFunction = Area_DoorTouch; } if (door->v.spawnflags & DOOR_FLAG_TRIGGERAUTO) { } if (door->v.spawnflags & DOOR_FLAG_TRIGGERDAMAGE) { // Give it at least one HP. if (!door->v.health) { door->v.health = 1; } door->v.takedamage = true; // TODO: add handler for this! // Entity_SetDamagedFunction(door, Area_DoorTouch); } if (door->local.damage) { Entity_SetBlockedFunction(door, Area_DoorBlocked); } }
void Waypoint_Spawn(MathVector3f_t vOrigin,WaypointType_t type) { #ifdef DEBUG_WAYPOINT char *cModelName = WAYPOINT_MODEL_BASE; #endif int iPointContents; Waypoint_t *wPoint; /* TODO If we're between two other waypoints and they can be seen then slot ourselves in so that we act as the last waypoint instead. */ iPointContents = Engine.Server_PointContents(vOrigin); // [17/6/2012] Check that this area is safe ~hogsy if(iPointContents == BSP_CONTENTS_SOLID) { Engine.Con_Warning("Failed to place waypoint, position is within a solid!\n"); return; } { Waypoint_t *wVisibleWaypoint = Waypoint_GetByVisibility(vOrigin); // [30/1/2013] Oops! Check we actually have a visible waypoint!! ~hogsy if(wVisibleWaypoint) { MathVector3f_t vDistance; Math_VectorSubtract(wVisibleWaypoint->position,vOrigin,vDistance); if(Math_VectorLength(vDistance) < MONSTER_RANGE_MEDIUM) { Engine.Con_Printf("Invalid waypoint position!\n"); return; } } } wPoint = Waypoint_Allocate(); if(!wPoint) { Engine.Con_Warning("Failed to allocate waypoint!\n"); return; } Math_VectorCopy(vOrigin,wPoint->position); wPoint->number = waypoint_count; wPoint->bOpen = false; wPoint->next = Waypoint_GetByNumber(wPoint->number+1); wPoint->last = Waypoint_GetByNumber(wPoint->number-1); wPoint->wType = type; switch(type) { case WAYPOINT_ITEM: wPoint->cName = "item"; #ifdef DEBUG_WAYPOINT cModelName = WAYPOINT_MODEL_ITEM; #endif break; case WAYPOINT_CLIMB: wPoint->cName = "climb"; // TODO: Check that there's a ladder nearby. #ifdef DEBUG_WAYPOINT cModelName = WAYPOINT_MODEL_CLIMB; #endif break; case WAYPOINT_COVER: wPoint->cName = "cover"; // [27/12/2012] TODO: Check that this is actually cover ~hogsy break; case WAYPOINT_TYPE_JUMP: wPoint->cName = "jump"; // [27/12/2012] TODO: Check if this is actually a jump by tracing out ahead ~hogsy #ifdef DEBUG_WAYPOINT cModelName = WAYPOINT_MODEL_JUMP; #endif break; case WAYPOINT_TYPE_SWIM: if(iPointContents != BSP_CONTENTS_WATER) { Engine.Con_Warning("Waypoint with type swim not within water contents (%i %i %i)!", (int)vOrigin[0], (int)vOrigin[1], (int)vOrigin[2]); Waypoint_Delete(wPoint); return; } wPoint->cName = "swim"; #ifdef DEBUG_WAYPOINT cModelName = WAYPOINT_MODEL_SWIM; #endif break; case WAYPOINT_TYPE_DEFAULT: wPoint->cName = "default"; break; case WAYPOINT_SPAWN: wPoint->cName = "spawn"; break; default: Engine.Con_Warning("Unknown waypoint type (%i)!\n",type); Waypoint_Delete(wPoint); return; } // [30/1/2013] Pathetic reordering... Ugh ~hogsy if(!wPoint->last) { wPoint->last = Waypoint_GetByVisibility(vOrigin); if(!wPoint->last) { Engine.Con_Warning("Failed to get another visible waypoint! (%i)\n",wPoint->number); return; } } else if(wPoint->last != wPoint && wPoint->last->next) wPoint->last->next = wPoint; #ifdef DEBUG_WAYPOINT wPoint->eDebug = Entity_Spawn(); if(wPoint->eDebug) { wPoint->eDebug->v.effects = EF_MOTION_ROTATE; Entity_SetModel(wPoint->eDebug,cModelName); Entity_SetSizeVector(wPoint->eDebug,g_mvOrigin3f,g_mvOrigin3f); Entity_SetOrigin(wPoint->eDebug,wPoint->position); } Engine.Con_DPrintf("Waypoint placed (%i %i %i)\n", (int)wPoint->position[0], (int)wPoint->position[1], (int)wPoint->position[2]); Engine.Con_DPrintf(" number: %i\n",wPoint->number); Engine.Con_DPrintf(" type: %i\n",wPoint->wType); #endif }