Entity* Bullet_Create(float x, float y, float angle, Weapon* parent) { Entity* bullet = Entity_Spawn(); bullet->t = Cat_Bullet; bullet->sub_category = parent->type; bullet->x = x; bullet->y = y; bullet->movementC = MovementC_Create(); bullet->angle = angle; bullet->movementC->speed = parent->bullet_speed; bullet->movementC->dx = cos(angle) * bullet->movementC->speed; bullet->movementC->dy = sin(angle) * bullet->movementC->speed; bullet->is_ennemy = parent->is_monster; bullet->alive_timer = (1/bullet->movementC->speed) * 1500; bullet->damage = parent->bullet_damage; bullet->box.height = parent->bullet_height; bullet->box.width = parent->bullet_width; bullet->penetration_chance = parent->bullet_penetration_chance; bullet->last_zombie_hit = NULL; BoundingBox_Create(bullet, bullet->box.width, bullet->box.height); return bullet; }
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 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; }
// [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 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; } }
Entity* Decal_Create(Decal_Type type, float x, float y, float angle) { Entity* decals = Entity_Spawn(); decals->solid = false; decals->t = Cat_Decal; decals->sub_category = type; //alright so angle shouldn't be in movementC... F**K decals->movementC = MovementC_Create(); decals->angle = angle; int width = 40; int height = 40; switch(type) { case Decal_Corpse_Normal: break; case Decal_Corpse_Heavy: break; case Decal_Corpse_Trooper: width = 60; height = 45; break; case Decal_Corpse_Fast: break; case Decal_Corpse_Huge: width = 150; height = 150; break; case Decal_Corpse_Raptor: width = 120; height = 120; break; case Decal_Corpse_Destroyer: width = 260; height = 260; break; case Decal_Rug_Ancient: width = 20; height = 60; break; } if(type != Decal_Rug_Ancient ) { decals->is_ennemy = true; } decals->box = BoundingBox_CreateBetter(x, y, width, height); decals->x = x; decals->y = y; return decals; }
// [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); }
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 Hermes_PrimaryAttack(edict_t *ent) { float *dir; edict_t *cloud = Entity_Spawn(); cloud->v.cClassname = "cloud"; cloud->v.movetype = MOVETYPE_FLYMISSILE; cloud->Physics.iSolid = SOLID_TRIGGER; cloud->local.hit = 10; cloud->local.eOwner = ent; //SetSize(cloud,-16,-16,-16,16,16,16); Entity_SetOrigin(cloud,ent->v.origin); Engine.MakeVectors(ent->v.v_angle); dir = Engine.Aim(ent); cloud->v.velocity[0] = dir[0]*100; cloud->v.velocity[1] = dir[1]*100; cloud->v.velocity[2] = dir[2]*100; cloud->v.dNextThink = Server.dTime+0.3; cloud->v.think = Hermes_CloudThink; cloud->v.TouchFunction = HermesCloudTouch; Math_VectorAddValue(cloud->v.avelocity,300.0f,cloud->v.avelocity); if(ent->local.attackb_finished > Server.dTime) // No attack boost... ent->local.dAttackFinished = Server.dTime+0.35; else ent->local.dAttackFinished = Server.dTime+0.7; #if 0 if(rand()%3 == 1) //Weapon_Animate(ent,FALSE,12,17,0.07f,10,19,0,FALSE); else if(rand()%3 == 2) //Weapon_Animate(ent,FALSE,18,23,0.07f,10,19,0,FALSE); else //Weapon_Animate(ent,FALSE,24,29,0.07f,10,19,0,FALSE); #endif }
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()); } }
ServerEntity_t *Area_SpawnTriggerField(ServerEntity_t *owner, PLVector3D mins, PLVector3D maxs, void (*TriggerFunction)(ServerEntity_t *entity, ServerEntity_t *other)) { if ((mins == 0) || (maxs == 0)) { g_engine->Con_Warning("Invalid size for trigger field!"); return NULL; } ServerEntity_t *field = Entity_Spawn(); field->v.movetype = MOVETYPE_NONE; field->local.owner = owner; Entity_SetTouchFunction(field, TriggerFunction); Entity_SetPhysics(field, SOLID_TRIGGER, 0, 0); // Set the size of it. PLVector3D tmins = mins, tmaxs = maxs; tmins.x -= 60; tmins.y -= 60; tmins.z -= 8; tmaxs.x += 60; tmaxs.y += 60; tmaxs.z += 8; Entity_SetSizeVector(field, tmins, tmaxs); return field; }
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; }
void Hermes_PrimaryAttack(ServerEntity_t *ent) { ServerEntity_t *cloud = Entity_Spawn(); cloud->v.classname = "cloud"; cloud->v.movetype = MOVETYPE_FLYMISSILE; cloud->Physics.solid = SOLID_TRIGGER; cloud->local.hit = 10; cloud->local.owner = ent; //SetSize(cloud,-16,-16,-16,16,16,16); Entity_SetOrigin(cloud,ent->v.origin); Weapon_Projectile(ent, cloud, 100.0f); cloud->v.nextthink = Server.time+0.3; cloud->v.think = Hermes_CloudThink; cloud->v.TouchFunction = HermesCloudTouch; plAddVector3Df(&cloud->v.avelocity, 300); if(ent->local.attackb_finished > Server.time) // No attack boost... ent->local.dAttackFinished = Server.time+0.35; else ent->local.dAttackFinished = Server.time+0.7; #if 0 if(rand()%3 == 1) //Weapon_Animate(ent,FALSE,12,17,0.07f,10,19,0,FALSE); else if(rand()%3 == 2) //Weapon_Animate(ent,FALSE,18,23,0.07f,10,19,0,FALSE); else //Weapon_Animate(ent,FALSE,24,29,0.07f,10,19,0,FALSE); #endif }
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 }
/* Called when a monster/entity gets killed. */ void Monster_Killed(edict_t *eTarget,edict_t *eAttacker) { if(eTarget->monster.iState == STATE_DEAD) return; if(Entity_IsMonster(eTarget)) { WriteByte(MSG_ALL,SVC_KILLEDMONSTER); Server.iMonsters--; eAttacker->v.iScore++; #if 0 // Update number of frags for client. Engine.SetMessageEntity(eAttacker); Engine.WriteByte(MSG_ONE,SVC_UPDATESTAT); Engine.WriteByte(MSG_ONE,STAT_FRAGS); Engine.WriteByte(MSG_ONE,eAttacker->v.iScore); #endif } else if(Entity_IsPlayer(eAttacker) && bIsMultiplayer) { char *cDeathMessage = "%s was killed by %s\n"; if(eTarget == eAttacker) { cDeathMessage = "%s killed himself!\n"; eAttacker->v.iScore--; } else if(Entity_IsPlayer(eTarget) && bIsCooperative) { cDeathMessage = "%s was tk'd by %s (what a dick, huh?)"; eAttacker->v.iScore--; } // [2/9/2012] Did we kill someone while dead? ~hogsy else { eAttacker->v.iScore++; // [15/12/2013] Extra points! ~hogsy if(eAttacker->v.iHealth <= 0) { // [3/10/2012] TODO: Play sound ~hogsy Engine.CenterPrint(eAttacker,"FROM BEYOND THE GRAVE!\n"); cDeathMessage = "%s was killed from beyond the grave by %s\n"; eAttacker->v.iScore += 2; } // [15/12/2013] Extra points! ~hogsy if(!(eTarget->v.flags & FL_ONGROUND)) { // [25/6/2012] TODO: Play sound ~hogsy Engine.CenterPrint(eAttacker,"WATCH THEM DROP!\n"); cDeathMessage = "%s was shot out of the air by %s\n"; eAttacker->v.iScore += 2; } } // Update number of frags for client. Engine.SetMessageEntity(eAttacker); Engine.WriteByte(MSG_ONE,SVC_UPDATESTAT); Engine.WriteByte(MSG_ONE,STAT_FRAGS); Engine.WriteByte(MSG_ONE,eAttacker->v.iScore); // TODO: move Kill messages into mode_deathmatch (?) Create Weapon specific kill messages and more variations! ~eukos Engine.Server_BroadcastPrint(cDeathMessage,eTarget->v.netname,eAttacker->v.netname); } else eTarget->v.bTakeDamage = false; #ifdef GAME_OPENKATANA // [22/4/2014] Drop the currently equipped item for the player to pick up! ~hogsy { Weapon_t *wActive = Weapon_GetCurrentWeapon(eTarget); if(wActive && (wActive->iItem != WEAPON_LASERS)) { edict_t *eDroppedItem = Entity_Spawn(); Math_VectorCopy(eTarget->v.origin,eDroppedItem->v.origin); eDroppedItem->local.style = wActive->iItem; Item_Spawn(eDroppedItem); } } #endif if(eTarget->monster.think_die) eTarget->monster.think_die(eTarget,eAttacker); // Update our current state. eTarget->monster.iState = STATE_DEAD; }
/* 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; }
void Level_Load(char* file_name, World* w) { Level_Clear(w); FILE *save_file; save_file = fopen(file_name, "rb"); if(!save_file) { printf("Can't open file"); } printf("gggggg"); int nb_of_walls = 0; fread(&nb_of_walls, sizeof(int), 1, save_file); for(int i = 0 ; i < nb_of_walls ; i++) { Entity* buffer = (Entity*)malloc(sizeof(Entity)); //Entity_Spawn(); fread(buffer, sizeof(Entity), 1, save_file); int position_in_array = buffer->x / TILE_SIZE + ((buffer->y/ TILE_SIZE) * w->map_width); w->map[position_in_array] = buffer; } for(int i = 0 ; i < w->map_size ; i++) { Entity* buffer = (Entity*)malloc(sizeof(Entity)); //Entity_Spawn(); fread(buffer, sizeof(Entity), 1, save_file); int position_in_array = buffer->x / TILE_SIZE + ((buffer->y/ TILE_SIZE) * w->map_width); w->ground_map[position_in_array] = buffer; } printf("mdr"); int num_of_events = 0; fread(&num_of_events, sizeof(int), 1, save_file); for(int i = 0 ; i < num_of_events ; i++) { Entity* buffer = Entity_Spawn(); LevelEditor_ReadEntity(save_file, buffer, w); Vector_Push(&w->events_vector, buffer); } printf("mdr"); int num_of_props = 0; fread(&num_of_props, sizeof(int), 1, save_file); for(int i = 0 ; i < num_of_props; i++) { Entity* buffer = Entity_Spawn(); LevelEditor_ReadEntity(save_file, buffer, w); Vector_Push(&w->props_vector, buffer); } int num_of_zombies = 0; fread(&num_of_zombies, sizeof(int), 1, save_file); printf("Loading %d mobs\n", num_of_zombies); if(num_of_zombies != 0) { for(int i = 0 ; i < num_of_zombies ; i++) { Entity* buffer = Entity_Spawn(); LevelEditor_ReadEntity(save_file, buffer, w); Vector_Push(&w->monsters_vector, buffer); } } int num_of_decalss = 0; fread(&num_of_decalss, sizeof(int), 1, save_file); printf("Loading %d decals\n", num_of_decalss); for(int i = 0 ; i < num_of_decalss ; i++) { Entity* buffer = Entity_Spawn(); LevelEditor_ReadEntity(save_file, buffer, w); Vector_Push(&w->decals_vector, buffer); } int num_of_bonus = 0; fread(&num_of_bonus, sizeof(int), 1, save_file); for(int i = 0 ; i < num_of_bonus ; i++) { Entity* buffer = Entity_Spawn(); LevelEditor_ReadEntity(save_file, buffer, w); Vector_Push(&w->bonus_vector, buffer); } fclose(save_file); }
Entity* Prop_Create(Bonus_type type, float x, float y, float angle) { Entity* prop = Entity_Spawn(); prop->x = x; prop->y = y; prop->t = Cat_Prop; prop->sub_category = type; prop->angle = angle; prop->hp = 10; /*bbox changes depending on the angle*/ int true_x, true_y, true_width, true_height; switch(type) { case Prop_Bed: prop->width = 32; prop->height = 64; break; case Prop_Desk: prop->width = 25; prop->height = 40; break; case Prop_Chair: prop->width = 20; prop->height = 20; break; case Prop_Car_Cool: prop->width = 60; prop->height = 120; prop->hp = 25; break; case Prop_Bookcase: prop->width = 32; prop->height = 32; break; case Prop_FileCabinet: prop->width = 32; prop->height = 32; break; case Prop_BlackChest: prop->width = 32; prop->height = 32; break; case Prop_Refrigerator: prop->width = 32; prop->height = 32; break; case Prop_Kitchen_Stove: prop->width = 32; prop->height = 32; break; case Prop_Kitchen_Table: prop->width = 32; prop->height = 32; break; case Prop_Couch_Blue: prop->width = 64; prop->height = 32; break; case Prop_Plant: prop->width = 24; prop->height = 24; break; case Prop_LivingRoom_TV: prop->width = 64; prop->height = 32; break; case Prop_Office_Desk_Computer: prop->width = 64; prop->height = 26; break; case Prop_Bathroom_Sink: prop->width = 32; prop->height = 26; break; case Prop_Bathtub: prop->width = 64; prop->height = 32; break; case Prop_WC: prop->width = 32; prop->height = 32; break; case Prop_Cupboard: prop->width = 64; prop->height = 32; break; case Prop_Dining_Room_Table_Large: prop->width = 64; prop->height = 96; break; } true_width = prop->width; true_height = prop->height; true_x = x; true_y = y; int xCenter = x + prop->width / 2; int yCenter = y + prop->height / 2; if(angle > HALF_PI - 0.1 && angle < HALF_PI + 0.1) { true_x = xCenter - (cos(angle) * (x - xCenter)) + (sin(angle) * (y - yCenter)); true_y = yCenter + sin(angle) * (x - xCenter) + cos(angle) * (y - yCenter); true_width = prop->height; true_height = prop->width; } else if(angle > PI + HALF_PI - 0.1 && angle < PI + HALF_PI + 0.1) { true_x = xCenter + cos(angle) * (x - xCenter) - sin(angle) * (y - yCenter); true_y = yCenter - sin(angle) * (x - xCenter) + cos(angle) * (y - yCenter); true_width = prop->height; true_height = prop->width; } prop->box = BoundingBox_CreateBetter(true_x, true_y, true_width, true_height); return prop; }