//***********************************************************************************************
// flags & 1 == destroyed !
//***********************************************************************************************
void ARX_EQUIPMENT_UnEquip(Entity * target, Entity * tounequip, long flags)
{
	if(!target || !tounequip)
		return;

	if(target != entities.player())
		return;

	for(size_t i = 0; i < MAX_EQUIPED; i++) {
		if(ValidIONum(player.equiped[i]) && entities[player.equiped[i]] == tounequip) {
			EERIE_LINKEDOBJ_UnLinkObjectFromObject(target->obj, tounequip->obj);
			ARX_EQUIPMENT_Release(player.equiped[i]);
			target->bbox2D.min.x = 9999;
			target->bbox2D.max.x = -9999;
			
			if(!flags) {
				if(!DRAGINTER) {
					ARX_SOUND_PlayInterface(SND_INVSTD);
					Set_DragInter(tounequip);
				} else {
					giveToPlayer(tounequip);
				}
			}
			
			EVENT_SENDER = tounequip;
			SendIOScriptEvent(entities.player(), SM_EQUIPOUT);
			EVENT_SENDER = entities.player();
			SendIOScriptEvent(tounequip, SM_EQUIPOUT);
		}
	}

	if(tounequip->type_flags & (OBJECT_TYPE_HELMET | OBJECT_TYPE_ARMOR | OBJECT_TYPE_LEGGINGS))
		ARX_EQUIPMENT_RecreatePlayerMesh();
}
Beispiel #2
0
static void EntityLeavingLastZone(Entity * io, ARX_PATH * last) {
	
	SendIOScriptEvent(NULL, io, SM_LEAVEZONE, last->name);
	
	if(!last->controled.empty()) {
		EntityHandle t = entities.getById(last->controled);
		if(t != EntityHandle()) {
			ScriptParameters parameters;
			parameters.push_back(io->idString());
			parameters.push_back(last->name);
			SendIOScriptEvent(NULL, entities[t], SM_CONTROLLEDZONE_LEAVE, parameters);
		}
	}
	
}
void SecondaryInventoryHud::updateFader() {
	
	if(m_fadeDirection != Fade_stable) {
		if((player.Interface & INTER_COMBATMODE) || player.doingmagic >= 2 || m_fadeDirection == Fade_left) {
			if(m_fadePosition > -160)
				m_fadePosition -= (g_framedelay * ( 1.0f / 3 )) * m_scale;
		} else {
			if(m_fadePosition < 0)
				m_fadePosition += m_fadeDirection * (g_framedelay * ( 1.0f / 3 )) * m_scale;
		}
		
		if(m_fadePosition <= -160) {
			m_fadePosition = -160;
			m_fadeDirection = Fade_stable;
			
			if(player.Interface & INTER_STEAL || ioSteal) {
				SendIOScriptEvent(ioSteal, SM_STEAL, "off");
				player.Interface &= ~INTER_STEAL;
				ioSteal = NULL;
			}
			
			SecondaryInventory = NULL;
			TSecondaryInventory = NULL;
			m_fadeDirection = Fade_stable;
		} else if(m_fadePosition >= 0) {
			m_fadePosition = 0;
			m_fadeDirection = Fade_stable;
		}
	}
}
Beispiel #4
0
static void EntityEnteringCurrentZone2(Entity * io, ARX_PATH * current) {
	
	io->inzone_show = io->show;
	SendIOScriptEvent(NULL, io, SM_ENTERZONE, current->name);
	
	if(!current->controled.empty()) {
		EntityHandle t = entities.getById(current->controled);
		if(t != EntityHandle()) {
			ScriptParameters parameters;
			parameters.push_back(io->idString());
			parameters.push_back(current->name);
			SendIOScriptEvent(NULL, entities[t], SM_CONTROLLEDZONE_ENTER, parameters);
		}
	}
	
}
Beispiel #5
0
void StealIconGui::updateInput() {
	
	// steal
	if(player.Interface & INTER_STEAL) {
		if(m_rect.contains(Vec2f(DANAEMouse))) {
			
			eMouseState = MOUSE_IN_STEAL_ICON;
			cursorSetInteraction();
			
			if(eeMouseDown1()) {
				ARX_INVENTORY_OpenClose(ioSteal);
				
				if(player.Interface & (INTER_INVENTORY | INTER_INVENTORYALL)) {
					ARX_SOUND_PlayInterface(SND_BACKPACK, Random::getf(0.9f, 1.1f));
				}
				
				if(SecondaryInventory) {
					SendIOScriptEvent(entities.player(), ioSteal, SM_STEAL);
					bForceEscapeFreeLook = true;
					lOldTruePlayerMouseLook = !TRUE_PLAYER_MOUSELOOK_ON;
				}
			}
			
			if(DRAGINTER == NULL) {
				return;
			}
			
		}
	}
	
}
void SecondaryInventoryCloseHudIcon::updateInput() {
	
	m_isSelected = m_rect.contains(Vec2f(DANAEMouse));
	
	if(m_isSelected) {
		SpecialCursor=CURSOR_INTERACTION_ON;
		
		if(eeMouseDown1()) {
			Entity * io = NULL;
			
			if(SecondaryInventory)
				io = SecondaryInventory->io;
			else if(player.Interface & INTER_STEAL)
				io = ioSteal;
			
			if(io) {
				ARX_SOUND_PlayInterface(SND_BACKPACK, Random::getf(0.9f, 1.1f));
				g_secondaryInventoryHud.m_fadeDirection = SecondaryInventoryHud::Fade_left;
				SendIOScriptEvent(io,SM_INVENTORY2_CLOSE);
				TSecondaryInventory=SecondaryInventory;
				SecondaryInventory=NULL;
			}
		}
		
		if(DRAGINTER == NULL)
			return;
	}
}
Beispiel #7
0
void ARX_DAMAGES_DurabilityLoss(Entity * io, float loss)
{
	if(!io)
		return;

	io->durability -= loss;

	if(io->durability <= 0) {
		SendIOScriptEvent(io, SM_BREAK);
	}
}
Beispiel #8
0
void ARX_SCRIPT_AllowInterScriptExec() {
	
	ARX_PROFILE_FUNC();
	
	// FIXME static local variable
	static long ppos = 0;
	
	if(arxtime.is_paused()) {
		return;
	}
	
	EVENT_SENDER = NULL;
	
	long heartbeat_count = std::min(long(entities.size()), 10l);
	
	for(long n = 0; n < heartbeat_count; n++) {
		
		EntityHandle i = EntityHandle(ppos++);
		if(i >= long(entities.size())){
			ppos = 0;
			return;
		}
		
		if(entities[i] == NULL || !(entities[i]->gameFlags & GFLAG_ISINTREATZONE)) {
			continue;
		}
		
		if(!entities[i]->mainevent.empty()) {
			
			// Copy the even name to a local variable as it may change during execution
			// and cause unexpected behavior in SendIOScriptEvent
			std::string event = entities[i]->mainevent;
			
			SendIOScriptEvent(entities[i], SM_NULL, std::string(), event);
			
		} else {
			SendIOScriptEvent(entities[i], SM_MAIN);
		}
	}
}
Beispiel #9
0
static void EntityEnteringCurrentZone(Entity * io, ARX_PATH * current) {
	
	io->inzone_show = io->show;
	
	if(JUST_RELOADED && (current->name == "ingot_maker" || current->name == "mauld_user")) {
		ARX_DEAD_CODE(); // TODO remove JUST_RELOADED global
	} else {
		
		SendIOScriptEvent(NULL, io, SM_ENTERZONE, current->name);
		
		if(!current->controled.empty()) {
			EntityHandle t = entities.getById(current->controled);
			if(t != EntityHandle()) {
				ScriptParameters parameters;
				parameters.push_back(io->idString());
				parameters.push_back(current->name);
				SendIOScriptEvent(NULL, entities[t], SM_CONTROLLEDZONE_ENTER, parameters);
			}
		}
		
	}
	
}
Beispiel #10
0
static void ARX_DAMAGES_IgnitIO(Entity * io, float dmg)
{
	if(!io || (io->ioflags & IO_INVULNERABILITY))
		return;

	if(io->ignition <= 0.f && io->ignition + dmg > 1.f)
		SendIOScriptEvent(io, SM_ENTERZONE, "cook_s");

	if(io->ioflags & IO_FIX)
		io->ignition += dmg * ( 1.0f / 10 );
	else if(io->ioflags & IO_ITEM)
		io->ignition += dmg * ( 1.0f / 8 );
	else if(io->ioflags & IO_NPC)
		io->ignition += dmg * ( 1.0f / 4 );
}
void SecondaryInventoryHud::close() {
	
	Entity * io = NULL;
	
	if(SecondaryInventory)
		io = SecondaryInventory->io;
	else if(player.Interface & INTER_STEAL)
		io = ioSteal;
	
	if(io) {
		m_fadeDirection = Fade_left;
		SendIOScriptEvent(io, SM_INVENTORY2_CLOSE);
		TSecondaryInventory = SecondaryInventory;
		SecondaryInventory = NULL;
	}
}
Beispiel #12
0
ScriptResult SendMsgToAllIO(ScriptMessage msg, const std::string & params) {
	
	ScriptResult ret = ACCEPT;
	
	for(size_t i = 0; i < entities.size(); i++) {
		const EntityHandle handle = EntityHandle(i);
		Entity * e = entities[handle];
		
		if(e) {
			if(SendIOScriptEvent(e, msg, params) == REFUSE) {
				ret = REFUSE;
			}
		}
	}
	
	return ret;
}
void SecondaryInventoryHud::update() {
	Entity * io = getSecondaryOrStealInvEntity();
	if(io) {
		float dist = fdist(io->pos, player.pos + (Vec3f_Y_AXIS * 80.f));
		
		float maxDist = player.m_telekinesis ? 900.f : 350.f;
		
		if(dist > maxDist) {
			if(m_fadeDirection != Fade_left) {
				ARX_SOUND_PlayInterface(SND_BACKPACK, Random::getf(0.9f, 1.1f));
				
				m_fadeDirection = Fade_left;
				SendIOScriptEvent(io,SM_INVENTORY2_CLOSE);
				TSecondaryInventory=SecondaryInventory;
				SecondaryInventory=NULL;
			} else {
				if(player.Interface & INTER_STEAL) {
					player.Interface &= ~INTER_STEAL;
				}
			}
		}
	} else if(m_fadeDirection != Fade_left) {
		m_fadeDirection = Fade_left;
	}
	
	
	if(!(player.Interface & INTER_COMBATMODE) && (player.Interface & INTER_MINIBACK)) {
		// Pick All/Close Secondary Inventory
		if(TSecondaryInventory) {
			//These have to be calculated on each frame (to make them move).
			Rectf parent = Rectf(Vec2f(m_fadePosition, 0), m_defaultBackground->m_size.x * m_scale, m_defaultBackground->m_size.y * m_scale);
			
			m_pickAllButton.setScale(m_scale);
			m_closeButton.setScale(m_scale);
			
			m_pickAllButton.update(parent);
			m_closeButton.update(parent);
		}
	}
}
Beispiel #14
0
void ARX_DAMAGES_ForceDeath(Entity * io_dead, Entity * io_killer) {
	
	if(io_dead->mainevent == "dead") {
		return;
	}

	Entity * old_sender = EVENT_SENDER;
	EVENT_SENDER = io_killer;

	if(io_dead == DRAGINTER)
		Set_DragInter(NULL);

	if(io_dead == FlyingOverIO)
		FlyingOverIO = NULL;

	if((MasterCamera.exist & 1) && (MasterCamera.io == io_dead))
		MasterCamera.exist = 0;

	if((MasterCamera.exist & 2) && (MasterCamera.want_io == io_dead))
		MasterCamera.exist = 0;

	lightHandleDestroy(io_dead->dynlight);
	lightHandleDestroy(io_dead->halo.dynlight);
	
	//Kill all speeches

	ARX_NPC_Behaviour_Reset(io_dead);

	ARX_SPEECH_ReleaseIOSpeech(io_dead);

	//Kill all Timers...
	ARX_SCRIPT_Timer_Clear_For_IO(io_dead);

	if(io_dead->mainevent != "dead") {
		if(SendIOScriptEvent(io_dead, SM_DIE) != REFUSE && ValidIOAddress(io_dead)) {
			io_dead->infracolor = Color3f::blue;
		}
	}
	
	if (!ValidIOAddress(io_dead))
		return;

	ARX_SCRIPT_SetMainEvent(io_dead, "dead");

	if(fartherThan(io_dead->pos, ACTIVECAM->orgTrans.pos, 3200.f)) {
		io_dead->animlayer[0].ctime = 9999999;
		io_dead->animBlend.lastanimtime = 0;
	}

	std::string killer;

	if(io_dead->ioflags & IO_NPC)
		io_dead->_npcdata->weaponinhand = 0;

	ARX_INTERACTIVE_DestroyDynamicInfo(io_dead);

	if(io_killer == entities.player()) {
		killer = "player";
	} else {
		if(io_killer)
			killer = io_killer->idString();
	}

	for(size_t i = 1; i < entities.size(); i++) {
		const EntityHandle handle = EntityHandle(i);
		Entity * ioo = entities[handle];

		if(ioo == io_dead)
			continue;

		if(ioo && (ioo->ioflags & IO_NPC)) {
			if(ValidIONum(ioo->targetinfo))
				if(entities[ioo->targetinfo] == io_dead) {
					EVENT_SENDER = io_dead; 
					Stack_SendIOScriptEvent(entities[handle], SM_NULL, killer, "target_death");
					ioo->targetinfo = EntityHandle(TARGET_NONE);
					ioo->_npcdata->reachedtarget = 0;
				}

			if(ValidIONum(ioo->_npcdata->pathfind.truetarget))
				if(entities[ioo->_npcdata->pathfind.truetarget] == io_dead) {
					EVENT_SENDER = io_dead; 
					Stack_SendIOScriptEvent(entities[handle], SM_NULL, killer, "target_death");
					ioo->_npcdata->pathfind.truetarget = EntityHandle(TARGET_NONE);
					ioo->_npcdata->reachedtarget = 0;
				}
		}
	}

	io_dead->animlayer[1].cur_anim = NULL;
	io_dead->animlayer[2].cur_anim = NULL;
	io_dead->animlayer[3].cur_anim = NULL;

	if(io_dead->ioflags & IO_NPC) {
		io_dead->_npcdata->lifePool.current = 0;

		if(io_dead->_npcdata->weapon) {
			Entity * ioo = io_dead->_npcdata->weapon;
			if(ValidIOAddress(ioo)) {
				ioo->show = SHOW_FLAG_IN_SCENE;
				ioo->ioflags |= IO_NO_NPC_COLLIDE;
				ioo->pos = ioo->obj->vertexlist3[ioo->obj->origin].v;
				ioo->velocity = Vec3f(0.f, 13.f, 0.f);
				ioo->stopped = 0;
			}
		}
	}

	EVENT_SENDER = old_sender;
}
Beispiel #15
0
void ARX_DAMAGES_DamageFIX(Entity * io, float dmg, EntityHandle source, bool isSpellHit)
{
	if(   !io
	   || !io->show
	   || !(io->ioflags & IO_FIX)
	   || (io->ioflags & IO_INVULNERABILITY)
	   || !io->script.data
	) {
		return;
	}

	io->dmg_sum += dmg;

	if (ValidIONum(source))
		EVENT_SENDER = entities[source];
	else
		EVENT_SENDER = NULL;

	if(float(arxtime) > io->ouch_time + 500) {
		io->ouch_time = (unsigned long)(arxtime);
		char tex[32];
		sprintf(tex, "%5.2f", io->dmg_sum);
		SendIOScriptEvent(io, SM_OUCH, tex);
		io->dmg_sum = 0.f;
	}

	if(rnd() * 100.f > io->durability)
		io->durability -= dmg * ( 1.0f / 2 ); //1.f;

	if(io->durability <= 0.f) {
		io->durability = 0.f;
		SendIOScriptEvent(io, SM_BREAK);
	} else {
		char dmm[32];

		if(EVENT_SENDER == entities.player()) {
			if(isSpellHit) {
				sprintf(dmm, "%f spell", dmg);
			}
			else
				switch(ARX_EQUIPMENT_GetPlayerWeaponType())
				{
					case WEAPON_BARE:
						sprintf(dmm, "%f bare", dmg);
						break;
					case WEAPON_DAGGER:
						sprintf(dmm, "%f dagger", dmg);
						break;
					case WEAPON_1H:
						sprintf(dmm, "%f 1h", dmg);
						break;
					case WEAPON_2H:
						sprintf(dmm, "%f 2h", dmg);
						break;
					case WEAPON_BOW:
						sprintf(dmm, "%f arrow", dmg);
						break;
					default:
						sprintf(dmm, "%f", dmg);
						break;
				}
		}
		else
			sprintf(dmm, "%f", dmg);

		if(SendIOScriptEvent(io, SM_HIT, dmm) != ACCEPT)
			return;
	}
}
Beispiel #16
0
float ARX_DAMAGES_DamagePlayer(float dmg, DamageType type, EntityHandle source) {
	if (player.playerflags & PLAYERFLAGS_INVULNERABILITY)
		return 0;

	float damagesdone = 0.f;

	if(player.lifePool.current == 0.f)
		return damagesdone;

	if(dmg > player.lifePool.current)
		damagesdone = dmg;
	else
		damagesdone = player.lifePool.current;

	entities.player()->dmg_sum += dmg;

	if(float(arxtime) > entities.player()->ouch_time + 500) {
		Entity * oes = EVENT_SENDER;

		if(ValidIONum(source))
			EVENT_SENDER = entities[source];
		else
			EVENT_SENDER = NULL;

		entities.player()->ouch_time = (unsigned long)(arxtime);
		char tex[32];
		sprintf(tex, "%5.2f", entities.player()->dmg_sum);
		SendIOScriptEvent( entities.player(), SM_OUCH, tex );
		EVENT_SENDER = oes;
		float power = entities.player()->dmg_sum / player.lifePool.max * 220.f;
		AddQuakeFX(power * 3.5f, 500 + power * 3, rnd() * 100.f + power + 200, 0);
		entities.player()->dmg_sum = 0.f;
	}

	if(dmg > 0.f) {
		if(ValidIONum(source)) {
			Entity * pio = NULL;

			if(entities[source]->ioflags & IO_NPC) {
				pio = entities[source]->_npcdata->weapon;

				if(pio && (pio->poisonous == 0 || pio->poisonous_count == 0))
					pio = NULL;
			}

			if(!pio)
				pio = entities[source];

			if(pio && pio->poisonous && pio->poisonous_count != 0) {
				if(rnd() * 100.f > player.m_misc.resistPoison) {
					player.poison += pio->poisonous;
				}

				if(pio->poisonous_count != -1)
					pio->poisonous_count--;
			}
		}

		long alive;

		if(player.lifePool.current > 0)
			alive = 1;
		else
			alive = 0;

		if(!BLOCK_PLAYER_CONTROLS)
			player.lifePool.current -= dmg;

		if(player.lifePool.current <= 0.f) {
			player.lifePool.current = 0.f;

			if(alive) {
				//REFUSE_GAME_RETURN = 1;
				ARX_PLAYER_BecomesDead();

				if((type & DAMAGE_TYPE_FIRE) || (type & DAMAGE_TYPE_FAKEFIRE)) {
					ARX_SOUND_PlayInterface(SND_PLAYER_DEATH_BY_FIRE);
				}

				SendIOScriptEvent(entities.player(), SM_DIE);

				for(size_t i = 1; i < entities.size(); i++) {
					const EntityHandle handle = EntityHandle(i);
					Entity * ioo = entities[handle];
					
					if(ioo && (ioo->ioflags & IO_NPC)) {
						if(ioo->targetinfo == TARGET_PLAYER) {
							EVENT_SENDER = entities.player();
							std::string killer;
							if(source == PlayerEntityHandle) {
								killer = "player";
							} else if(source <= EntityHandle::Invalid) {
								killer = "none";
							} else if(ValidIONum(source)) {
								killer = entities[source]->idString();
							}
							SendIOScriptEvent(entities[handle], SM_NULL, killer, "target_death");
						}
					}
				}
			}
		}

		if(player.lifePool.max <= 0.f)
			return damagesdone;

		float t = dmg / player.lifePool.max;

		if(Blood_Pos == 0.f) {
			Blood_Pos = 0.000001f;
			Blood_Duration = 100 + (t * 200.f);
		} else {
			long temp = t * 800.f;
			Blood_Duration += temp;
		}
	}

	// revient les barres
	ResetPlayerInterface();

	return damagesdone;
}
Beispiel #17
0
void SummonCreatureSpell::Update() {
	
	if(arxtime.is_paused())
		return;
	
	float elapsed = arxtime.now_f() - m_timcreation;
	
	if(elapsed <= 4000) {
		if(Random::getf() > 0.7f) {
			Vec3f pos = m_fissure.m_eSrc;
			MakeCoolFx(pos);
		}
		
		m_fissure.Update(g_framedelay);
		m_fissure.Render();
		
		m_requestSummon = true;
		m_summonedEntity = EntityHandle();

	} else if(m_requestSummon) {
		lightHandleDestroy(m_light);
		
		m_requestSummon = false;
		ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &m_targetPos);
		
		Cylinder phys = Cylinder(m_targetPos, 50, -200);
		
		float anything = CheckAnythingInCylinder(phys, NULL, CFLAG_JUST_TEST);
		
		if(glm::abs(anything) < 30) {
			
			long tokeep;
			res::path cls;
			if(m_megaCheat) {
				if(Random::getf() > 0.5f) {
					tokeep = -1;
					cls = "graph/obj3d/interactive/npc/wrat_base/wrat_base";
				} else {
					tokeep = 0;
					cls = "graph/obj3d/interactive/npc/y_mx/y_mx";
				}
			} else if(Random::getf() > 0.997f || (sp_max && Random::getf() > 0.8f)
			   || (cur_mr >= 3 && Random::getf() > 0.3f)) {
				tokeep = 0;
				cls = "graph/obj3d/interactive/npc/y_mx/y_mx";
			} else if(Random::getf() > 0.997f || (cur_rf >= 3 && Random::getf() > 0.8f)
			   || (cur_mr >= 3 && Random::getf() > 0.3f)) {
				tokeep = -1;
				cls = "graph/obj3d/interactive/npc/wrat_base/wrat_base";
			} else if(m_level >= 9) {
				tokeep = 1;
				cls = "graph/obj3d/interactive/npc/demon/demon";
			} else if(Random::getf() > 0.98f) {
				tokeep = -1;
				cls = "graph/obj3d/interactive/npc/wrat_base/wrat_base";
			} else {
				tokeep = 0;
				cls = "graph/obj3d/interactive/npc/chicken_base/chicken_base";
			}
			
			Entity * io = AddNPC(cls, -1, IO_IMMEDIATELOAD);
			if(!io) {
				cls = "graph/obj3d/interactive/npc/chicken_base/chicken_base";
				tokeep = 0;
				io = AddNPC(cls, -1, IO_IMMEDIATELOAD);
			}
			
			if(io) {
				RestoreInitialIOStatusOfIO(io);
				
				io->summoner = m_caster;
				
				io->scriptload = 1;
				
				if(tokeep == 1) {
					io->ioflags |= IO_NOSAVE;
				}
				
				io->pos = phys.origin;
				SendInitScriptEvent(io);
				
				if(tokeep < 0) {
					io->scale=1.65f;
					io->physics.cyl.radius=25;
					io->physics.cyl.height=-43;
					io->speed_modif=1.f;
				}
				
				if(ValidIONum(m_caster)) {
					EVENT_SENDER = entities[m_caster];
				} else {
					EVENT_SENDER = NULL;
				}
				
				SendIOScriptEvent(io,SM_SUMMONED);
				
				for(long j = 0; j < 3; j++) {
					Vec3f pos = m_fissure.m_eSrc;
					pos += randomVec3f() * 100.f;
					pos += Vec3f(-50.f, 50.f, -50.f);
					
					MakeCoolFx(pos);
				}
				
				if(tokeep==1)
					m_summonedEntity = io->index();
				else
					m_summonedEntity = EntityHandle();
			}
		}
	} else if(m_summonedEntity == EntityHandle()) {
		m_duration = 0;
	}
}
void ControlTargetSpell::Launch()
{
	// TODO copy-paste
	for(size_t ii = 1; ii < entities.size(); ii++) {
		const EntityHandle handle = EntityHandle(ii);
		Entity * ioo = entities[handle];
		
		if(!ioo || !(ioo->ioflags & IO_NPC)) {
			continue;
		}
		
		if(ioo->_npcdata->lifePool.current <= 0.f || ioo->show != SHOW_FLAG_IN_SCENE) {
			continue;
		}
		
		if(ioo->groups.find("demon") == ioo->groups.end()) {
			continue;
		}
		
		if(closerThan(ioo->pos, m_caster_pos, 900.f)) {
			std::ostringstream oss;
			oss << entities[m_target]->idString();
			oss << ' ' << long(m_level);
			SendIOScriptEvent(ioo, SM_NULL, oss.str(), "npc_control");
		}
	}
	
	ARX_SOUND_PlaySFX(SND_SPELL_CONTROL_TARGET);
	
	m_duration = 1000;
	
	eSrc = Vec3f_ZERO;
	eTarget = Vec3f_ZERO;
	fTrail = 0.f;
	
	tex_mm = TextureContainer::Load("graph/obj3d/textures/(fx)_ctrl_target");
	
	eSrc = player.pos;
	
	float fBetaRad = glm::radians(player.angle.getPitch());
	float fBetaRadCos = glm::cos(fBetaRad);
	float fBetaRadSin = glm::sin(fBetaRad);
	
	eTarget = eSrc + Vec3f(-fBetaRadSin * 1000.f, 100.f, fBetaRadCos * 1000.f);
	
	for(size_t i = 1; i < entities.size(); i++) {
		const EntityHandle handle = EntityHandle(i);
		Entity * e = entities[handle];
		
		if(e) {
			eTarget = e->pos;
		}
	}
	
	Vec3f h;
	Vec3f s = eSrc;
	Vec3f e = eSrc;
	int i = 0;
	while(Visible(s, e, &h) && i < 20) {
		e.x -= fBetaRadSin * 50;
		e.z += fBetaRadCos * 50;
		i++;
	}
	
	pathways[0] = eSrc + Vec3f(0.f, 100.f, 0.f);
	pathways[9] = eTarget;
	Split(pathways, 0, 9, 150);
	
	for(int i = 0; i < 9; i++) {
		if(pathways[i].y >= eSrc.y + 150) {
			pathways[i].y = eSrc.y + 150;
		}
	}
	
	fTrail = 0;
}
Beispiel #19
0
void ARX_PATH_UpdateAllZoneInOutInside() {
	
	arx_assert(entities.player());
	
	static size_t count = 1;
	
	long f = glm::clamp(static_cast<long>(framedelay), 10l, 50l);
	
	if(count >= entities.size()) {
		count = 1;
	}

	if(entities.size() > 1)
		for(long tt = 0; tt < f; tt++) {
			const EntityHandle i = EntityHandle(count);
			Entity * io = entities[i];
			

			if(count < entities.size()
			   && io
			   && io->ioflags & (IO_NPC | IO_ITEM)
			   && io->show != SHOW_FLAG_MEGAHIDE
			) {
				arx_assert(io->show != SHOW_FLAG_DESTROYED);
				ARX_PATH * p = ARX_PATH_CheckInZone(io);
				ARX_PATH * op = io->inzone;

				if(op == NULL && p == NULL)
					goto next; // Not in a zone

				if(op == p) { // Stayed inside Zone OP
					if(io->show != io->inzone_show) {
						io->inzone_show = io->show;
						goto entering;
					}
				}
				else if ((op != NULL) && (p == NULL)) // Leaving Zone OP
				{
					SendIOScriptEvent(io, SM_LEAVEZONE, op->name);

					if(!op->controled.empty()) {
						EntityHandle t = entities.getById(op->controled);

						if(t != EntityHandle::Invalid) {
							std::string str = io->idString() + ' ' + op->name;
							SendIOScriptEvent(entities[t], SM_CONTROLLEDZONE_LEAVE, str);
						}
					}
				}
				else if ((op == NULL) && (p != NULL)) // Entering Zone P
				{
					io->inzone_show = io->show;
				entering:

					if(JUST_RELOADED && (p->name == "ingot_maker" || p->name == "mauld_user")) {
						ARX_DEAD_CODE(); // TODO remove JUST_RELOADED global
					} else {
						SendIOScriptEvent(io, SM_ENTERZONE, p->name);

						if(!p->controled.empty()) {
							EntityHandle t = entities.getById(p->controled);

							if(t != EntityHandle::Invalid) {
								std::string params = io->idString() + ' ' + p->name;
								SendIOScriptEvent(entities[t], SM_CONTROLLEDZONE_ENTER, params);
							}
						}
					}
				} else {
					SendIOScriptEvent(io, SM_LEAVEZONE, op->name);

					if(!op->controled.empty()) {
						EntityHandle t = entities.getById(op->controled);

						if(t != EntityHandle::Invalid) {
							std::string str = io->idString() + ' ' + op->name;
							SendIOScriptEvent(entities[t], SM_CONTROLLEDZONE_LEAVE, str);
						}
					}

					io->inzone_show = io->show;
					SendIOScriptEvent(io, SM_ENTERZONE, p->name);

					if(!p->controled.empty()) {
						EntityHandle t = entities.getById(p->controled);

						if(t != EntityHandle::Invalid) {
							std::string str = io->idString() + ' ' + p->name;
							SendIOScriptEvent(entities[t], SM_CONTROLLEDZONE_ENTER, str);
						}
					}
				}

				io->inzone = p;
			}

		next:
			count++;

			if(count >= entities.size())
				count = 1;
		}

	// player check*************************************************
	{
		ARX_PATH * p = ARX_PATH_CheckPlayerInZone();
		ARX_PATH * op = player.inzone;

		if((op == NULL) && (p == NULL))
			goto suite; // Not in a zone

		if(op == p) // Stayed inside Zone OP
		{
		
		}
		else if(op != NULL && p == NULL) // Leaving Zone OP
		{
			SendIOScriptEvent(entities.player(), SM_LEAVEZONE, op->name);
			CHANGE_LEVEL_ICON = -1;

			if(!op->controled.empty()) {
				EntityHandle t = entities.getById(op->controled);

				if(t != EntityHandle::Invalid) {
					SendIOScriptEvent(entities[t], SM_CONTROLLEDZONE_LEAVE, "player " + op->name);
				}
			}
		}
		else if ((op == NULL) && (p != NULL)) // Entering Zone P
		{
			SendIOScriptEvent(entities.player(), SM_ENTERZONE, p->name);

			if(p->flags & PATH_AMBIANCE && !p->ambiance.empty())
				ARX_SOUND_PlayZoneAmbiance(p->ambiance, ARX_SOUND_PLAY_LOOPED, p->amb_max_vol * ( 1.0f / 100 ));

			if(p->flags & PATH_FARCLIP) {
				desired.flags |= GMOD_ZCLIP;
				desired.zclip = p->farclip;
			}

			if (p->flags & PATH_REVERB)
			{
			}

			if(p->flags & PATH_RGB) {
				desired.flags |= GMOD_DCOLOR;
				desired.depthcolor = p->rgb;
			}

			if(!p->controled.empty()) {
				EntityHandle t = entities.getById(p->controled);

				if(t != EntityHandle::Invalid) {
					SendIOScriptEvent(entities[t], SM_CONTROLLEDZONE_ENTER, "player " + p->name);
				}
			}
		} else {
			if(!op->controled.empty()) {
				EntityHandle t = entities.getById(op->controled);

				if(t != EntityHandle::Invalid) {
					SendIOScriptEvent(entities[t], SM_CONTROLLEDZONE_LEAVE, "player " + p->name);
				}
			}

			if(!op->controled.empty()) {
				EntityHandle t = entities.getById(p->controled);

				if(t != EntityHandle::Invalid) {
					SendIOScriptEvent(entities[t], SM_CONTROLLEDZONE_ENTER, "player " + p->name);
				}
			}
		}

		player.inzone = p;
	}

	
suite:
	JUST_RELOADED = 0;
}
Beispiel #20
0
void TreatBackgroundDynlights() {
	
	ARX_PROFILE_FUNC();
	
	for(size_t i = 0; i < g_staticLightsMax; i++) {
		EERIE_LIGHT * light = g_staticLights[i];
		
		if(light && (light->extras & EXTRAS_SEMIDYNAMIC)) {
			
			float fMaxdist = player.m_telekinesis ? 850 : 300;
			
			if(!fartherThan(light->pos, g_camera->m_pos, fMaxdist)) {
				ComputeLight2DPos(light);
			} else {
				light->m_screenRect = Rectf(1, 0, -1, 0); // Intentionally invalid
			}
			
			if(!light->m_ignitionStatus) {
				
				// just extinguished
				EERIE_LIGHT * dynLight = lightHandleGet(light->m_ignitionLightHandle);
				if(dynLight) {
					dynLight->m_exists = false;
					light->m_ignitionLightHandle = LightHandle();
					for(size_t l = 0; l < entities.size(); l++) {
						const EntityHandle handle = EntityHandle(l);
						Entity * e = entities[handle];
						if(e && (e->ioflags & IO_MARKER)) {
							Vec3f _pos2 = GetItemWorldPosition(e);
							if(!fartherThan(light->pos, _pos2, 300.f)) {
								SendIOScriptEvent(NULL, e, SM_CUSTOM, "douse");
							}
						}
					}
				}
				
			} else {
				
				// just light up
				if(!lightHandleGet(light->m_ignitionLightHandle)) {
					for(size_t l = 0; l < entities.size(); l++) {
						const EntityHandle handle = EntityHandle(l);
						Entity * e = entities[handle];
						if(e && (e->ioflags & IO_MARKER)) {
							Vec3f _pos2 = GetItemWorldPosition(e);
							if(!fartherThan(light->pos, _pos2, 300.f)) {
								SendIOScriptEvent(NULL, e, SM_CUSTOM, "fire");
							}
						}
					}
					light->m_ignitionLightHandle = GetFreeDynLight();
				}
				
				EERIE_LIGHT * dynamicLight = lightHandleGet(light->m_ignitionLightHandle);
				if(dynamicLight) {
					dynamicLight->pos          = light->pos;
					dynamicLight->fallstart    = light->fallstart;
					dynamicLight->fallend      = light->fallend;
					dynamicLight->m_isIgnitionLight  = true;
					dynamicLight->intensity    = light->intensity;
					dynamicLight->ex_flaresize = light->ex_flaresize;
					dynamicLight->extras       = light->extras;
					dynamicLight->duration     = GameDurationMs(std::numeric_limits<long>::max());
					
					dynamicLight->rgb = light->rgb - light->rgb * light->ex_flicker * randomColor3f() * 0.5f;
					
					dynamicLight->rgb = componentwise_max(dynamicLight->rgb, Color3f::black);
					RecalcLight(dynamicLight);
				}
			}
		}
	}

	for(size_t i = 0; i < g_dynamicLightsMax; i++) {
		EERIE_LIGHT * el = &g_dynamicLights[i];

		if(el->m_exists && el->duration != 0) {
			const GameDuration elapsed = g_gameTime.now() - el->creationTime;
			const GameDuration duration = el->duration;

			if(elapsed >= duration) {
				float sub = g_gameTime.lastFrameDuration() / GameDurationMs(1000);

				el->rgb.r -= sub;
				el->rgb.g -= sub;
				el->rgb.b -= sub;

				if(el->rgb.r < 0)
					el->rgb.r = 0.f;

				if(el->rgb.g < 0)
					el->rgb.g = 0.f;

				if(el->rgb.b < 0)
					el->rgb.b = 0.f;

				if(el->rgb.r + el->rgb.g + el->rgb.b == 0) {
					el->m_exists = false;
					el->duration = 0;
				}
			}
		}
	}
}
Beispiel #21
0
void ManageCombatModeAnimations() {
	arx_assert(entities.player());
		
	Entity * const io = entities.player();
	
	AnimLayer & layer1 = io->animlayer[1];

	ANIM_HANDLE ** alist=io->anims;
	WeaponType weapontype = ARX_EQUIPMENT_GetPlayerWeaponType();
	
	if(weapontype == WEAPON_BARE && LAST_WEAPON_TYPE != weapontype) {
		if(layer1.cur_anim != alist[ANIM_BARE_WAIT]) {
			changeAnimation(io, 1, alist[ANIM_BARE_WAIT]);
			AimTime = 0;
		}
	}
	
	switch(weapontype) {
		case WEAPON_BARE:	// BARE HANDS PLAYER MANAGEMENT

			if(layer1.cur_anim == alist[ANIM_BARE_WAIT]) {
				AimTime = 0;
				if(eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT_START + CurrFightPos * 3]);
					io->isHit = false;
				}
			}

			// Now go for strike cycle...
			for(long j = 0; j < 4; j++) {
				if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT_START+j*3] && (layer1.flags & EA_ANIMEND)) {
					changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP);
					AimTime = (unsigned long)(arxtime);
				} else if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT_CYCLE+j*3] && !eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT + j * 3]);
					strikeSpeak(io);
					SendIOScriptEvent(io, SM_STRIKE, "bare");
					PlayerWeaponBlocked = -1;
					CurrFightPos = 0;
					AimTime = 0;
				} else if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT+j*3]) {
					if(layer1.flags & EA_ANIMEND) {
						changeAnimation(io, 1, alist[ANIM_BARE_WAIT], EA_LOOP);
						CurrFightPos = 0;
						AimTime = (unsigned long)(arxtime);
						PlayerWeaponBlocked = -1;
					} else if(layer1.ctime > layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.2f
							&& layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.8f
							&& PlayerWeaponBlocked == -1
					) {
						long id = -1;
						
						if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT]) {
							id = io->obj->fastaccess.left_attach;
						} else { // Strike Right
							id = io->obj->fastaccess.primary_attach;
						}
						
						if(id != -1) {
							Sphere sphere;
							sphere.origin = io->obj->vertexlist3[id].v;
							sphere.radius = 25.f;
							
							EntityHandle num;
							
							if(CheckAnythingInSphere(sphere, PlayerEntityHandle, 0, &num)) {
								float dmgs = (player.m_miscFull.damages + 1) * STRIKE_AIMTIME;
								
								if(ARX_DAMAGES_TryToDoDamage(io->obj->vertexlist3[id].v, dmgs, 40, PlayerEntityHandle)) {
									PlayerWeaponBlocked = layer1.ctime;
								}
								
								ARX_PARTICLES_Spawn_Spark(sphere.origin, int(dmgs), 2);
								
								if(ValidIONum(num)) {
									ARX_SOUND_PlayCollision(entities[num]->material, MATERIAL_FLESH, 1.f, 1.f, sphere.origin, NULL);
								}
							}
						}
					}
				}
			}

		break;
		case WEAPON_DAGGER: // DAGGER PLAYER MANAGEMENT
			
			// Waiting and receiving Strike Impulse
			if(layer1.cur_anim == alist[ANIM_DAGGER_WAIT]) {
				AimTime = 0;
				if(eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT_START + CurrFightPos * 3]);
					io->isHit = false;
				}
			}

			// Now go for strike cycle...
			for(long j = 0; j < 4; j++) {
				if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT_START+j*3] && (layer1.flags & EA_ANIMEND)) {
					changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP);
					AimTime = (unsigned long)(arxtime);
				} else if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT_CYCLE+j*3] && !eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT + j * 3]);
					strikeSpeak(io);
					SendIOScriptEvent(io, SM_STRIKE, "dagger");
					CurrFightPos = 0;
					AimTime = 0;
				} else if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT+j*3]) {
					if(layer1.ctime > layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.3f
						&& layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.7f)
					{
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						
						if(PlayerWeaponBlocked == -1
							&& ARX_EQUIPMENT_Strike_Check(io, weapon, STRIKE_AIMTIME, 0))
						{
							PlayerWeaponBlocked = layer1.ctime;
						}
					}

					if(layer1.flags & EA_ANIMEND) {
						changeAnimation(io, 1, alist[ANIM_DAGGER_WAIT], EA_LOOP);
						layer1.flags &= ~(EA_PAUSED | EA_REVERSE);
						CurrFightPos = 0;
						AimTime = (unsigned long)(arxtime);
						PlayerWeaponBlocked = -1;
					}

					if(PlayerWeaponBlocked != -1 && layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.9f) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						ARX_EQUIPMENT_Strike_Check(io, weapon, STRIKE_AIMTIME, 1);
					}
				}
			}

		break;
		case WEAPON_1H: // 1HANDED PLAYER MANAGEMENT
			
			// Waiting and Received Strike Impulse
			if(layer1.cur_anim == alist[ANIM_1H_WAIT]) {
				AimTime = 0;
				if(eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT_START + CurrFightPos * 3]);
					io->isHit = false;
				}
			}

			// Now go for strike cycle...
			for(long j = 0; j < 4; j++) {
				if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT_START+j*3] && (layer1.flags & EA_ANIMEND)) {
					changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP);
					AimTime = (unsigned long)(arxtime);
				} else if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT_CYCLE+j*3] && !eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT + j * 3]);
					strikeSpeak(io);
					SendIOScriptEvent(io, SM_STRIKE, "1h");
					CurrFightPos = 0;
					AimTime = 0;
				} else if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT+j*3]) {
					if(layer1.ctime > layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.3f
						&& layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.7f)
					{
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						
						if(PlayerWeaponBlocked == -1
							&& ARX_EQUIPMENT_Strike_Check(io, weapon, STRIKE_AIMTIME, 0))
						{
							PlayerWeaponBlocked = layer1.ctime;
						}
					}

					if(layer1.flags & EA_ANIMEND) {
						changeAnimation(io, 1, alist[ANIM_1H_WAIT], EA_LOOP);
						layer1.flags &= ~(EA_PAUSED | EA_REVERSE);
						CurrFightPos = 0;
						AimTime = 0;
						PlayerWeaponBlocked = -1;
					}

					if(PlayerWeaponBlocked != -1 && layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.9f) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						ARX_EQUIPMENT_Strike_Check(io, weapon, STRIKE_AIMTIME, 1);
					}
				}
			}
		break;
		case WEAPON_2H: // 2HANDED PLAYER MANAGEMENT
			
			// Waiting and Receiving Strike Impulse
			if(layer1.cur_anim == alist[ANIM_2H_WAIT]) {
				AimTime = 0;
				if(eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT_START + CurrFightPos * 3]);
					io->isHit = false;
				}
			}

			// Now go for strike cycle...
			for(long j = 0; j < 4; j++) {
				if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT_START+j*3] && (layer1.flags & EA_ANIMEND)) {
					changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP);
					AimTime = (unsigned long)(arxtime);
				} else if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT_CYCLE+j*3] && !eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT + j * 3]);
					strikeSpeak(io);
					SendIOScriptEvent(io, SM_STRIKE, "2h");
					CurrFightPos = 0;
					AimTime = 0;
				} else if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT+j*3]) {
					if(layer1.ctime > layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.3f
						&& layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.7f)
					{
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						
						if(PlayerWeaponBlocked == -1
							&& ARX_EQUIPMENT_Strike_Check(io, weapon, STRIKE_AIMTIME, 0))
						{
							PlayerWeaponBlocked = layer1.ctime;
						}
					}

					if(layer1.flags & EA_ANIMEND) {
						changeAnimation(io, 1, alist[ANIM_2H_WAIT], EA_LOOP);
						layer1.flags &= ~(EA_PAUSED | EA_REVERSE);
						CurrFightPos = 0;
						AimTime = 0;
						PlayerWeaponBlocked = -1;
					}

					if(PlayerWeaponBlocked != -1 && layer1.ctime < layer1.cur_anim->anims[layer1.altidx_cur]->anim_time * 0.9f) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						ARX_EQUIPMENT_Strike_Check(io, weapon, STRIKE_AIMTIME, 1);
					}
				}
			}
		break;
		case WEAPON_BOW: // MISSILE PLAYER MANAGEMENT
			if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_CYCLE]) {
				if(GLOBAL_SLOWDOWN != 1.f)
					BOW_FOCAL += Original_framedelay;
				else
					BOW_FOCAL += framedelay;

				if(BOW_FOCAL > 710)
					BOW_FOCAL = 710;
			}

			// Waiting and Receiving Strike Impulse
			if(layer1.cur_anim == alist[ANIM_MISSILE_WAIT]) {
				AimTime = (unsigned long)(arxtime);

				if(eeMousePressed1() && Player_Arrow_Count() > 0) {
					changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_PART_1]);
					io->isHit = false;
				}
			}

			if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_PART_1] && (layer1.flags & EA_ANIMEND)) {
				AimTime = 0;
				changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_PART_2]);
				EERIE_LINKEDOBJ_LinkObjectToObject(io->obj, arrowobj, "left_attach", "attach", NULL);
			}

			// Now go for strike cycle...
			if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_PART_2] && (layer1.flags & EA_ANIMEND)) {
				changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_CYCLE], EA_LOOP);
				AimTime = (unsigned long)(arxtime);
			} else if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_CYCLE] && !eeMousePressed1()) {
				EERIE_LINKEDOBJ_UnLinkObjectFromObject(io->obj, arrowobj);
				changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE]);
				SendIOScriptEvent(io, SM_STRIKE, "bow");
				StrikeAimtime();
				STRIKE_AIMTIME = (float)(BOW_FOCAL)/710.f;
				Entity * quiver = Player_Arrow_Count_Decrease();
				float poisonous = 0.f;

				if(quiver) {
					poisonous = quiver->poisonous;
					if(quiver->poisonous_count > 0) {
						quiver->poisonous_count--;

						if(quiver->poisonous_count <= 0)
							quiver->poisonous = 0;
					}

					ARX_DAMAGES_DurabilityLoss(quiver, 1.f);

					// TODO is this needed ?, quivers seem to self destruct via script, but maybe not all
					if(ValidIOAddress(quiver) && quiver->durability <= 0.f) {
						ARX_INTERACTIVE_DestroyIOdelayed(quiver);
					}
				}

				float aimratio = STRIKE_AIMTIME;

				if(sp_max && poisonous < 3.f)
					poisonous = 3.f;

				Vec3f orgPos = player.pos + Vec3f(0.f, 40.f, 0.f);

				if(io->obj->fastaccess.left_attach >= 0) {
					orgPos = io->obj->vertexlist3[io->obj->fastaccess.left_attach].v;
				}

				Anglef orgAngle = player.angle;

				PlayerLaunchArrow_Test(aimratio, poisonous, orgPos, orgAngle);

				if(sp_max) {
					Anglef angle;
					Vec3f pos = player.pos + Vec3f(0.f, 40.f, 0.f);
					
					angle.setYaw(player.angle.getYaw());
					angle.setPitch(player.angle.getPitch() + 8);
					angle.setRoll(player.angle.getRoll());
					PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle);
					angle.setYaw(player.angle.getYaw());
					angle.setPitch(player.angle.getPitch() - 8);
					PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle);
					angle.setYaw(player.angle.getYaw());
					angle.setPitch(player.angle.getPitch() + 4.f);
					PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle);
					angle.setYaw(player.angle.getYaw());
					angle.setPitch(player.angle.getPitch() - 4.f);
					PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle);
				}

				AimTime = 0;
			} else if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE]) {
				BOW_FOCAL -= Original_framedelay;

				if(BOW_FOCAL < 0)
					BOW_FOCAL = 0;

				if(layer1.flags & EA_ANIMEND) {
					BOW_FOCAL = 0;
					changeAnimation(io, 1, alist[ANIM_MISSILE_WAIT], EA_LOOP);
					AimTime = 0;
					PlayerWeaponBlocked = -1;
					EERIE_LINKEDOBJ_UnLinkObjectFromObject(io->obj, arrowobj);
				}
			}
		break;
	}

	LAST_WEAPON_TYPE = weapontype;
}
Beispiel #22
0
void ARX_PATH_UpdateAllZoneInOutInside() {
	
	ARX_PROFILE_FUNC();
	
	arx_assert(entities.player());
	
	static size_t count = 1;
	
	long f = glm::clamp(static_cast<long>(g_framedelay), 10l, 50l);
	
	if(count >= entities.size()) {
		count = 1;
	}

	if(entities.size() > 1) {
		for(long tt = 0; tt < f; tt++) {
			const EntityHandle i = EntityHandle(count);
			Entity * io = entities[i];
			
			if(   count < entities.size()
			   && io
			   && io->ioflags & (IO_NPC | IO_ITEM)
			   && io->show != SHOW_FLAG_MEGAHIDE
			) {
				arx_assert(io->show != SHOW_FLAG_DESTROYED);
				ARX_PATH * current = ARX_PATH_CheckInZone(io);
				ARX_PATH * last = io->inzone;
				
				if(!last && !current) { // Not in a zone
				} else if(last == current) { // Stayed inside last zone
					if(io->show != io->inzone_show) {
						EntityEnteringCurrentZone(io, current);
					}
				} else if(last && !current) { // Leaving last zone
					EntityLeavingLastZone(io, last);
				} else if(!last) { // Entering current zone
					EntityEnteringCurrentZone(io, current);
				} else { // Changed from last to current zone
					EntityLeavingLastZone(io, last);
					EntityEnteringCurrentZone2(io, current);
				}
				
				io->inzone = current;
			}
			
			count++;
			
			if(count >= entities.size())
				count = 1;
		}
	}

	// player check*************************************************
	{
		ARX_PATH * current = ARX_PATH_CheckPlayerInZone();
		ARX_PATH * last = player.inzone;

		if(!last && !current) { // Not in a zone
		} else if(last == current) { // Stayed inside last zone
		} else if(last && !current) { // Leaving last zone
			
			SendIOScriptEvent(NULL, entities.player(), SM_LEAVEZONE, last->name);
			CHANGE_LEVEL_ICON = NoChangeLevel;
			
			if(!last->controled.empty()) {
				EntityHandle t = entities.getById(last->controled);
				if(t != EntityHandle()) {
					ScriptParameters parameters;
					parameters.push_back("player");
					parameters.push_back(last->name);
					SendIOScriptEvent(NULL, entities[t], SM_CONTROLLEDZONE_LEAVE, parameters);
				}
			}
			
		} else if(!last) { // Entering current zone
			
			SendIOScriptEvent(NULL, entities.player(), SM_ENTERZONE, current->name);
			
			if(current->flags & PATH_AMBIANCE && !current->ambiance.empty()) {
				ARX_SOUND_PlayZoneAmbiance(current->ambiance, ARX_SOUND_PLAY_LOOPED, current->amb_max_vol * 0.01f);
			}
			
			if(current->flags & PATH_FARCLIP) {
				g_desiredFogParameters.flags |= GMOD_ZCLIP;
				g_desiredFogParameters.zclip = current->farclip;
			}
			
			if(current->flags & PATH_RGB) {
				g_desiredFogParameters.flags |= GMOD_DCOLOR;
				g_desiredFogParameters.depthcolor = current->rgb;
			}
			
			if(!current->controled.empty()) {
				EntityHandle t = entities.getById(current->controled);
				if(t != EntityHandle()) {
					ScriptParameters parameters;
					parameters.push_back("player");
					parameters.push_back(current->name);
					SendIOScriptEvent(NULL, entities[t], SM_CONTROLLEDZONE_ENTER, parameters);
				}
			}
			
		} else { // Changed from last to current zone
			
			if(!last->controled.empty()) {
				EntityHandle t = entities.getById(last->controled);
				if(t != EntityHandle()) {
					ScriptParameters parameters;
					parameters.push_back("player");
					parameters.push_back(last->name);
					SendIOScriptEvent(NULL, entities[t], SM_CONTROLLEDZONE_LEAVE, parameters);
				}
			}
			
			if(!last->controled.empty()) {
				EntityHandle t = entities.getById(current->controled);
				if(t != EntityHandle()) {
					ScriptParameters parameters;
					parameters.push_back("player");
					parameters.push_back(current->name);
					SendIOScriptEvent(NULL, entities[t], SM_CONTROLLEDZONE_ENTER, parameters);
				}
			}
			
		}

		player.inzone = current;
	}
	
	JUST_RELOADED = 0;
}
void RiseDeadSpell::Update(float timeDelta) {
	
	if(m_creationFailed) {
		m_light = LightHandle();
		return;
	}
	
	m_duration+=200;
	
	m_fissure.Update(timeDelta);
	m_fissure.Render();
	
	if(lightHandleIsValid(m_light)) {
		EERIE_LIGHT * light = lightHandleGet(m_light);
		
		light->intensity = 0.7f + 2.3f;
		light->fallend = 500.f;
		light->fallstart = 400.f;
		light->rgb = Color3f(0.8f, 0.2f, 0.2f);
		light->duration=800;
		light->time_creation = (unsigned long)(arxtime);
	}
	
	unsigned long tim = m_fissure.ulCurrentTime;
	
	if(tim > 3000 && m_entity == EntityHandle() && !m_creationFailed) {
		ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &m_targetPos);
		
		Cylinder phys = Cylinder(m_targetPos, 50, -200);
		
		float anything = CheckAnythingInCylinder(phys, NULL, CFLAG_JUST_TEST);
		
		if(glm::abs(anything) < 30) {
			
			const char * cls = "graph/obj3d/interactive/npc/undead_base/undead_base";
			Entity * io = AddNPC(cls, -1, IO_IMMEDIATELOAD);
			
			if(io) {
				ARX_INTERACTIVE_HideGore(io);
				RestoreInitialIOStatusOfIO(io);
				
				io->summoner = m_caster;
				
				io->ioflags|=IO_NOSAVE;
				m_entity = io->index();
				io->scriptload=1;
				
				ARX_INTERACTIVE_Teleport(io, phys.origin);
				SendInitScriptEvent(io);
				
				if(ValidIONum(m_caster)) {
					EVENT_SENDER = entities[m_caster];
				} else {
					EVENT_SENDER = NULL;
				}
				
				SendIOScriptEvent(io,SM_SUMMONED);
					
				Vec3f pos = m_fissure.m_eSrc;
				pos += randomVec3f() * 100.f;
				pos += Vec3f(-50.f, 50.f, -50.f);
				
				MakeCoolFx(pos);
			}
			
			m_light = LightHandle();
		} else {
			ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE);
			m_creationFailed = true;
			m_duration=0;
		}
	} else if(!arxtime.is_paused() && tim < 4000) {
	  if(Random::getf() > 0.95f) {
			MakeCoolFx(m_fissure.m_eSrc);
		}
	}
}
Beispiel #24
0
void ManageCombatModeAnimations() {
	
	arx_assert(entities.player());
	
	if(player.m_aimTime > 0) {
		player.m_aimTime += g_platformTime.lastFrameDuration();
	}
	
	Entity * const io = entities.player();
	
	AnimLayer & layer1 = io->animlayer[1];
	
	ANIM_HANDLE ** alist = io->anims;
	WeaponType weapontype = ARX_EQUIPMENT_GetPlayerWeaponType();
	
	if(weapontype == WEAPON_BARE && LAST_WEAPON_TYPE != weapontype) {
		if(layer1.cur_anim != alist[ANIM_BARE_WAIT]) {
			changeAnimation(io, 1, alist[ANIM_BARE_WAIT]);
			player.m_aimTime = 0;
		}
	}
	
	switch(weapontype) {
		case WEAPON_BARE: { // BARE HANDS PLAYER MANAGEMENT
			if(layer1.cur_anim == alist[ANIM_BARE_WAIT]) {
				player.m_aimTime = 0;
				if(eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT_START + player.m_strikeDirection * 3]);
					io->isHit = false;
				}
			}
			
			// Now go for strike cycle...
			for(long j = 0; j < 4; j++) {
				if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT_START + j * 3] && (layer1.flags & EA_ANIMEND)) {
					changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP);
					player.m_aimTime = PlatformDuration::ofRaw(1);
				} else if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT_CYCLE + j * 3] && !eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT + j * 3]);
					strikeSpeak(io);
					SendIOScriptEvent(NULL, io, SM_STRIKE, "bare");
					player.m_weaponBlocked = AnimationDuration::ofRaw(-1); // TODO inband signaling AnimationDuration
					player.m_strikeDirection = 0;
					player.m_aimTime = 0;
				} else if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT + j * 3]) {
					if(layer1.flags & EA_ANIMEND) {
						changeAnimation(io, 1, alist[ANIM_BARE_WAIT], EA_LOOP);
						player.m_strikeDirection = 0;
						player.m_aimTime = PlatformDuration::ofRaw(1);
						player.m_weaponBlocked = AnimationDuration::ofRaw(-1);
					} else if( layer1.ctime > layer1.currentAltAnim()->anim_time * 0.2f
					        && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.8f
					        && player.m_weaponBlocked == AnimationDuration::ofRaw(-1)) {
						
						ActionPoint id = ActionPoint();
						if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT]) {
							id = io->obj->fastaccess.left_attach;
						} else { // Strike Right
							id = io->obj->fastaccess.primary_attach;
						}
						
						if(id != ActionPoint()) {
							Sphere sphere;
							sphere.origin = actionPointPosition(io->obj, id);
							sphere.radius = 25.f;
							
							EntityHandle num;
							
							if(CheckAnythingInSphere(sphere, EntityHandle_Player, 0, &num)) {
								float dmgs = (player.m_miscFull.damages + 1) * player.m_strikeAimRatio;
								
								if(ARX_DAMAGES_TryToDoDamage(actionPointPosition(io->obj, id), dmgs, 40, EntityHandle_Player)) {
									player.m_weaponBlocked = layer1.ctime;
								}
								
								ParticleSparkSpawnContinous(sphere.origin, unsigned(dmgs), SpawnSparkType_Success);
								
								if(ValidIONum(num)) {
									static PlatformInstant lastHit = 0;
									PlatformInstant now = g_platformTime.frameStart();
									if(now - lastHit > toPlatformDuration(layer1.ctime)) {
										ARX_SOUND_PlayCollision(entities[num]->material, MATERIAL_FLESH, 1.f, 1.f, sphere.origin, NULL);
										lastHit = now;
									}
								}
							}
						}
					}
				}
			}
			break;
		}
		case WEAPON_DAGGER: { // DAGGER PLAYER MANAGEMENT
			// Waiting and receiving Strike Impulse
			if(layer1.cur_anim == alist[ANIM_DAGGER_WAIT]) {
				player.m_aimTime = 0;
				if(eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT_START + player.m_strikeDirection * 3]);
					io->isHit = false;
				}
			}
			
			// Now go for strike cycle...
			for(long j = 0; j < 4; j++) {
				if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT_START + j * 3] && (layer1.flags & EA_ANIMEND)) {
					changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP);
					player.m_aimTime = PlatformDuration::ofRaw(1);
				} else if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT_CYCLE + j * 3] && !eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT + j * 3]);
					strikeSpeak(io);
					SendIOScriptEvent(NULL, io, SM_STRIKE, "dagger");
					player.m_strikeDirection = 0;
					player.m_aimTime = 0;
				} else if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT + j * 3]) {
					if(   layer1.ctime > layer1.currentAltAnim()->anim_time * 0.3f
					   && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.7f
					) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						
						if(player.m_weaponBlocked == AnimationDuration::ofRaw(-1)
							&& ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 0))
						{
							player.m_weaponBlocked = layer1.ctime;
						}
					}
					
					if(layer1.flags & EA_ANIMEND) {
						changeAnimation(io, 1, alist[ANIM_DAGGER_WAIT], EA_LOOP);
						layer1.flags &= ~(EA_PAUSED | EA_REVERSE);
						player.m_strikeDirection = 0;
						player.m_aimTime = PlatformDuration::ofRaw(1);
						player.m_weaponBlocked = AnimationDuration::ofRaw(-1);
					}
					
					if(   player.m_weaponBlocked != AnimationDuration::ofRaw(-1)
					   && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.9f
					) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 1);
					}
				}
			}
			break;
		}
		case WEAPON_1H: { // 1HANDED PLAYER MANAGEMENT
			// Waiting and Received Strike Impulse
			if(layer1.cur_anim == alist[ANIM_1H_WAIT]) {
				player.m_aimTime = 0;
				if(eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT_START + player.m_strikeDirection * 3]);
					io->isHit = false;
				}
			}
			
			// Now go for strike cycle...
			for(long j = 0; j < 4; j++) {
				if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT_START + j * 3] && (layer1.flags & EA_ANIMEND)) {
					changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP);
					player.m_aimTime = PlatformDuration::ofRaw(1);
				} else if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT_CYCLE + j * 3] && !eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT + j * 3]);
					strikeSpeak(io);
					SendIOScriptEvent(NULL, io, SM_STRIKE, "1h");
					player.m_strikeDirection = 0;
					player.m_aimTime = 0;
				} else if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT + j * 3]) {
					if(   layer1.ctime > layer1.currentAltAnim()->anim_time * 0.3f
					   && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.7f
					) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						
						if(player.m_weaponBlocked == AnimationDuration::ofRaw(-1)
							&& ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 0))
						{
							player.m_weaponBlocked = layer1.ctime;
						}
					}
					
					if(layer1.flags & EA_ANIMEND) {
						changeAnimation(io, 1, alist[ANIM_1H_WAIT], EA_LOOP);
						layer1.flags &= ~(EA_PAUSED | EA_REVERSE);
						player.m_strikeDirection = 0;
						player.m_aimTime = 0;
						player.m_weaponBlocked = AnimationDuration::ofRaw(-1);
					}
					
					if(   player.m_weaponBlocked != AnimationDuration::ofRaw(-1)
					   && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.9f
					) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 1);
					}
				}
			}
			break;
		}
		case WEAPON_2H: { // 2HANDED PLAYER MANAGEMENT
			// Waiting and Receiving Strike Impulse
			if(layer1.cur_anim == alist[ANIM_2H_WAIT]) {
				player.m_aimTime = 0;
				if(eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT_START + player.m_strikeDirection * 3]);
					io->isHit = false;
				}
			}
			
			// Now go for strike cycle...
			for(long j = 0; j < 4; j++) {
				if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT_START + j * 3] && (layer1.flags & EA_ANIMEND)) {
					changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP);
					player.m_aimTime = PlatformDuration::ofRaw(1);
				} else if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT_CYCLE + j * 3] && !eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT + j * 3]);
					strikeSpeak(io);
					SendIOScriptEvent(NULL, io, SM_STRIKE, "2h");
					player.m_strikeDirection = 0;
					player.m_aimTime = 0;
				} else if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT + j * 3]) {
					if(   layer1.ctime > layer1.currentAltAnim()->anim_time * 0.3f
					   && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.7f
					) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						
						if(player.m_weaponBlocked == AnimationDuration::ofRaw(-1)
							&& ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 0))
						{
							player.m_weaponBlocked = layer1.ctime;
						}
					}
					
					if(layer1.flags & EA_ANIMEND) {
						changeAnimation(io, 1, alist[ANIM_2H_WAIT], EA_LOOP);
						layer1.flags &= ~(EA_PAUSED | EA_REVERSE);
						player.m_strikeDirection = 0;
						player.m_aimTime = 0;
						player.m_weaponBlocked = AnimationDuration::ofRaw(-1);
					}
					
					if(   player.m_weaponBlocked != AnimationDuration::ofRaw(-1)
					   && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.9f
					) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 1);
					}
				}
			}
			break;
		}
		case WEAPON_BOW: { // MISSILE PLAYER MANAGEMENT
			if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_CYCLE]) {
				player.m_bowAimRatio += bowZoomFromDuration(toMs(g_platformTime.lastFrameDuration()));
				
				if(player.m_bowAimRatio > 1.f)
					player.m_bowAimRatio = 1.f;
			}
			
			// Waiting and Receiving Strike Impulse
			if(layer1.cur_anim == alist[ANIM_MISSILE_WAIT]) {
				player.m_aimTime = PlatformDuration::ofRaw(1);
				
				if(eeMousePressed1() && Player_Arrow_Count() > 0) {
					changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_PART_1]);
					io->isHit = false;
				}
			}
			
			if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_PART_1] && (layer1.flags & EA_ANIMEND)) {
				player.m_aimTime = 0;
				changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_PART_2]);
				EERIE_LINKEDOBJ_LinkObjectToObject(io->obj, arrowobj, "left_attach", "attach", NULL);
			}
			
			// Now go for strike cycle...
			if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_PART_2] && (layer1.flags & EA_ANIMEND)) {
				changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_CYCLE], EA_LOOP);
				player.m_aimTime = PlatformDuration::ofRaw(1);
			} else if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_CYCLE] && !eeMousePressed1()) {
				EERIE_LINKEDOBJ_UnLinkObjectFromObject(io->obj, arrowobj);
				changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE]);
				SendIOScriptEvent(NULL, io, SM_STRIKE, "bow");
				StrikeAimtime();
				player.m_strikeAimRatio = player.m_bowAimRatio;
				Entity * quiver = Player_Arrow_Count_Decrease();
				float poisonous = 0.f;
				
				if(quiver) {
					poisonous = quiver->poisonous;
					if(quiver->poisonous_count > 0) {
						quiver->poisonous_count--;
						
						if(quiver->poisonous_count <= 0)
							quiver->poisonous = 0;
					}
					
					ARX_DAMAGES_DurabilityLoss(quiver, 1.f);
					
					// TODO is this needed ?, quivers seem to self destruct via script, but maybe not all
					if(ValidIOAddress(quiver) && quiver->durability <= 0.f) {
						ARX_INTERACTIVE_DestroyIOdelayed(quiver);
					}
				}
				
				float aimratio = player.m_strikeAimRatio;
				
				if(sp_max && poisonous < 3.f)
					poisonous = 3.f;
				
				Vec3f orgPos = player.pos + Vec3f(0.f, 40.f, 0.f);
				
				if(io->obj->fastaccess.left_attach != ActionPoint()) {
					orgPos = actionPointPosition(io->obj, io->obj->fastaccess.left_attach);
				}
				
				Anglef orgAngle = player.angle;
				
				PlayerLaunchArrow_Test(aimratio, poisonous, orgPos, orgAngle);
				
				if(sp_max) {
					Anglef angle;
					Vec3f pos = player.pos + Vec3f(0.f, 40.f, 0.f);
					
					angle.setPitch(player.angle.getPitch());
					angle.setYaw(player.angle.getYaw() + 8);
					angle.setRoll(player.angle.getRoll());
					PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle);
					angle.setPitch(player.angle.getPitch());
					angle.setYaw(player.angle.getYaw() - 8);
					PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle);
					angle.setPitch(player.angle.getPitch());
					angle.setYaw(player.angle.getYaw() + 4.f);
					PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle);
					angle.setPitch(player.angle.getPitch());
					angle.setYaw(player.angle.getYaw() - 4.f);
					PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle);
				}
				
				player.m_aimTime = 0;
			} else if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE]) {
				player.m_bowAimRatio -= bowZoomFromDuration(toMs(g_platformTime.lastFrameDuration()));
				
				if(player.m_bowAimRatio < 0)
					player.m_bowAimRatio = 0;
				
				if(layer1.flags & EA_ANIMEND) {
					player.m_bowAimRatio = 0;
					changeAnimation(io, 1, alist[ANIM_MISSILE_WAIT], EA_LOOP);
					player.m_aimTime = 0;
					player.m_weaponBlocked = AnimationDuration::ofRaw(-1);
					EERIE_LINKEDOBJ_UnLinkObjectFromObject(io->obj, arrowobj);
				}
			}
			break;
		}
	}
	
	LAST_WEAPON_TYPE = weapontype;
}
Beispiel #25
0
//*************************************************************************************
//*************************************************************************************
void TreatBackgroundDynlights()
{
    long n;

    for (size_t i = 0; i < MAX_LIGHTS; i++)
    {
        if ((GLight[i] != NULL) && (GLight[i]->extras & EXTRAS_SEMIDYNAMIC))
        {
            float fMaxdist = 300;

            if (Project.telekinesis) fMaxdist = 850;

            if(!fartherThan(GLight[i]->pos, ACTIVECAM->pos, fMaxdist)) {
                ComputeLight2DPos(GLight[i]);
            }

            if (GLight[i]->status == 0)
            {
                // vient de s'éteindre
                if (GLight[i]->tl > 0)
                {
                    DynLight[GLight[i]->tl].exist = 0;
                    GLight[i]->tl = -1;
                    Vec3f _pos2;

                    for (long l = 0; l < inter.nbmax; l++)
                    {
                        if ((inter.iobj[l] != NULL) &&
                                (inter.iobj[l]->ioflags & IO_MARKER))
                        {
                            GetItemWorldPosition(inter.iobj[l], &_pos2);

                            if(!fartherThan(GLight[i]->pos, _pos2, 300.f)) {
                                SendIOScriptEvent(inter.iobj[l], SM_CUSTOM, "douse");
                            }
                        }
                    }
                }
            }
            else
            {
                // vient de s'allumer
                if (GLight[i]->tl <= 0)
                {
                    Vec3f _pos2;

                    for (long l = 0; l < inter.nbmax; l++)
                    {
                        if ((inter.iobj[l] != NULL) &&
                                (inter.iobj[l]->ioflags & IO_MARKER))
                        {
                            GetItemWorldPosition(inter.iobj[l], &_pos2);

                            if(!fartherThan(GLight[i]->pos, _pos2, 300.f)) {
                                SendIOScriptEvent(inter.iobj[l], SM_CUSTOM, "fire");
                            }
                        }
                    }

                    GLight[i]->tl = GetFreeDynLight();
                }

                n = GLight[i]->tl;

                if (n != -1)
                {
                    DynLight[n].pos.x		=	GLight[i]->pos.x;
                    DynLight[n].pos.y		=	GLight[i]->pos.y;
                    DynLight[n].pos.z		=	GLight[i]->pos.z;
                    DynLight[n].exist		=	1;
                    DynLight[n].fallstart	=	GLight[i]->fallstart;
                    DynLight[n].fallend		=	GLight[i]->fallend;
                    DynLight[n].type		=	TYP_SPECIAL1;
                    DynLight[n].intensity	=	GLight[i]->intensity;
                    DynLight[n].ex_flaresize =	GLight[i]->ex_flaresize;
                    DynLight[n].extras		=	GLight[i]->extras;
                    DynLight[n].duration = std::numeric_limits<long>::max();

                    DynLight[n].rgb.r = GLight[i]->rgb.r - GLight[i]->rgb.r * GLight[i]->ex_flicker.r * rnd() * ( 1.0f / 2 );
                    DynLight[n].rgb.g = GLight[i]->rgb.g - GLight[i]->rgb.g * GLight[i]->ex_flicker.g * rnd() * ( 1.0f / 2 );
                    DynLight[n].rgb.b = GLight[i]->rgb.b - GLight[i]->rgb.b * GLight[i]->ex_flicker.b * rnd() * ( 1.0f / 2 );

                    if (DynLight[n].rgb.r < 0.f) DynLight[n].rgb.r = 0.f;

                    if (DynLight[n].rgb.g < 0.f) DynLight[n].rgb.g = 0.f;

                    if (DynLight[n].rgb.b < 0.f) DynLight[n].rgb.b = 0.f;

                    DynLight[n].rgb255.r = DynLight[n].rgb.r * 255.f;
                    DynLight[n].rgb255.g = DynLight[n].rgb.g * 255.f;
                    DynLight[n].rgb255.b = DynLight[n].rgb.b * 255.f;

                    DynLight[n].falldiff = DynLight[n].fallend - DynLight[n].fallstart;
                    DynLight[n].falldiffmul = 1.f / DynLight[n].falldiff;
                    DynLight[n].precalc = DynLight[n].intensity * GLOBAL_LIGHT_FACTOR;
                }
            }
        }

    }
}
Beispiel #26
0
static float ARX_THROWN_ComputeDamages(long thrownum, EntityHandle source,
                                       EntityHandle target) {
	
	float distance_limit = 1000.f;
	Entity * io_target = entities[target];
	Entity * io_source = entities[source];

	SendIOScriptEvent(io_target, SM_AGGRESSION);

	float distance = fdist(Thrown[thrownum].position, Thrown[thrownum].initial_position);
	float distance_modifier = 1.f;

	if(distance < distance_limit * 2.f) {
		distance_modifier = distance / distance_limit;

		if(distance_modifier < 0.5f)
			distance_modifier = 0.5f;
	} else {
		distance_modifier = 2.f;
	}

	float attack, dmgs, backstab, ac;

	backstab = 1.f;
	bool critical = false;

	if(source == 0) {
		attack = Thrown[thrownum].damages;

		if(Random::getf(0.f, 100.f) <= float(player.m_attributeFull.dexterity - 9) * 2.f
						   + float(player.m_skillFull.projectile * 0.2f)) {
			if(SendIOScriptEvent(io_source, SM_CRITICAL, "bow") != REFUSE)
				critical = true;
		}

		dmgs = attack;

		if(io_target->_npcdata->npcflags & NPCFLAG_BACKSTAB) {
			if(Random::getf(0.f, 100.f) <= player.m_skillFull.stealth) {
				if(SendIOScriptEvent(io_source, SM_BACKSTAB, "bow") != REFUSE)
					backstab = 1.5f;
			}
		}
	} else {
		// TODO treat NPC !!!

		ARX_DEAD_CODE();
		attack = 0;
		dmgs = 0;
	}

	float absorb;

	if(target == 0) {
		ac = player.m_miscFull.armorClass;
		absorb = player.m_skillFull.defense * .5f;
	} else {
		ac = ARX_INTERACTIVE_GetArmorClass(io_target);
		absorb = io_target->_npcdata->absorb;
	}

	char wmat[64];

	std::string _amat = "flesh";
	const std::string * amat = &_amat;

	strcpy(wmat, "dagger");

	if(!io_target->armormaterial.empty()) {
		amat = &io_target->armormaterial;
	}

	if(io_target == entities.player()) {
		if(ValidIONum(player.equiped[EQUIP_SLOT_ARMOR])) {
			Entity * io = entities[player.equiped[EQUIP_SLOT_ARMOR]];
			if(io && !io->armormaterial.empty()) {
				amat = &io->armormaterial;
			}
		}
	}

	float power;
	power = dmgs * ( 1.0f / 20 );

	if(power > 1.f)
		power = 1.f;

	power = power * 0.15f + 0.85f;

	ARX_SOUND_PlayCollision(*amat, wmat, power, 1.f, Thrown[thrownum].position, io_source);

	dmgs *= backstab;
	dmgs -= dmgs * (absorb * ( 1.0f / 100 ));

	float chance = 100.f - (ac - attack);
	float dice = Random::getf(0.f, 100.f);

	if(dice <= chance) {
		if(dmgs > 0.f) {
			if(critical)
				dmgs *= 1.5f;

			dmgs *= distance_modifier;
			return dmgs;
		}
	}

	return 0.f;
}
float ARX_EQUIPMENT_ComputeDamages(Entity * io_source, Entity * io_target, float ratioaim, Vec3f * position)
{
	EVENT_SENDER = io_source;
	SendIOScriptEvent(io_target, SM_AGGRESSION);

	if(!io_source || !io_target)
		return 0.f;

	if(!(io_target->ioflags & IO_NPC)) {
		if(io_target->ioflags & IO_FIX) {
			if (io_source == entities.player())
				ARX_DAMAGES_DamageFIX(io_target, player.m_miscFull.damages, PlayerEntityHandle, false);
			else if (io_source->ioflags & IO_NPC)
				ARX_DAMAGES_DamageFIX(io_target, io_source->_npcdata->damages, io_source->index(), false);
			else
				ARX_DAMAGES_DamageFIX(io_target, 1, io_source->index(), false);
		}

		return 0.f;
	}

	float attack, ac, damages;
	float backstab = 1.f;

	std::string _wmat = "bare";
	const std::string * wmat = &_wmat;
	
	std::string _amat = "flesh";
	const std::string * amat = &_amat;

	bool critical = false;

	if(io_source == entities.player()) {
		
		if(ValidIONum(player.equiped[EQUIP_SLOT_WEAPON])) {
			Entity * io = entities[player.equiped[EQUIP_SLOT_WEAPON]];
			if(io && !io->weaponmaterial.empty()) {
				wmat = &io->weaponmaterial;
			}
		}

		attack = player.m_miscFull.damages;

		if(Random::getf(0.f, 100.f) <= player.m_miscFull.criticalHit)
		{
			if(SendIOScriptEvent(io_source, SM_CRITICAL) != REFUSE)
				critical = true;
		}
		else
			critical = false;

		damages = attack * ratioaim; 

		if(io_target->_npcdata->npcflags & NPCFLAG_BACKSTAB) {
			if(Random::getf(0.f, 100.f) <= player.m_skillFull.stealth * ( 1.0f / 2 )) {
				if(SendIOScriptEvent(io_source, SM_BACKSTAB) != REFUSE)
					backstab = 1.5f; 
			}
		}
	} else {
		if(!(io_source->ioflags & IO_NPC)) // no NPC source...
			return 0.f;

		if(!io_source->weaponmaterial.empty()) {
			wmat = &io_source->weaponmaterial;
		}
		
		if(io_source->_npcdata->weapon) {
			Entity * iow = io_source->_npcdata->weapon;
			if(!iow->weaponmaterial.empty()) {
				wmat = &iow->weaponmaterial;
			}
		}
		
		attack = io_source->_npcdata->tohit;
		
		damages = io_source->_npcdata->damages * ratioaim * Random::getf(0.5f, 1.0f);

		SpellBase * spell = spells.getSpellOnTarget(io_source->index(), SPELL_CURSE);
		if(spell) {
			damages *= (1 - spell->m_level * 0.05f);
		}

		if(Random::getf(0.f, 100) <= io_source->_npcdata->critical) {
			if(SendIOScriptEvent(io_source, SM_CRITICAL) != REFUSE)
				critical = true;
		}
		else
			critical = false;

		if(Random::getf(0.f, 100.f) <= (float)io_source->_npcdata->backstab_skill) {
			if(SendIOScriptEvent(io_source, SM_BACKSTAB) != REFUSE)
				backstab = 1.5f; 
		}
	}

	float absorb;

	if(io_target == entities.player()) {
		ac = player.m_miscFull.armorClass;
		absorb = player.m_skillFull.defense * ( 1.0f / 2 );
	} else {
		ac = ARX_INTERACTIVE_GetArmorClass(io_target);
		absorb = io_target->_npcdata->absorb;
		
		SpellBase * spell = spells.getSpellOnTarget(io_target->index(), SPELL_CURSE);
		if(spell) {
			float modif = (1 - spell->m_level * 0.05f);
			ac *= modif;
			absorb *= modif;
		}
	}
	
	if(!io_target->armormaterial.empty()) {
		amat = &io_target->armormaterial;
	}
	
	if(io_target == entities.player()) {
		if(ValidIONum(player.equiped[EQUIP_SLOT_ARMOR])) {
			Entity * io = entities[player.equiped[EQUIP_SLOT_ARMOR]];
			if(io && !io->armormaterial.empty()) {
				amat = &io->armormaterial;
			}
		}
	}
	
	float dmgs = damages * backstab;
	dmgs -= dmgs * absorb * 0.01f;
	
	Vec3f pos = io_target->pos;
	float power = std::min(1.f, dmgs * 0.05f) * 0.1f + 0.9f;
	
	ARX_SOUND_PlayCollision(*amat, *wmat, power, 1.f, pos, io_source);
	
	float chance = 100.f - (ac - attack); 
	if(Random::getf(0.f, 100.f) > chance) {
		return 0.f;
	}
	
	ARX_SOUND_PlayCollision("flesh", *wmat, power, 1.f, pos, io_source);
	
	if(dmgs > 0.f) {
		
		if(critical) {
			dmgs *= 1.5f; 
		}
		
		if(io_target == entities.player()) {
			
			// TODO should this be player.pos - player.baseOffset() = player.basePosition()?
			Vec3f ppos = io_source->pos - (player.pos + player.baseOffset());
			ppos = glm::normalize(ppos);
			
			// Push the player
			PUSH_PLAYER_FORCE += ppos * -dmgs * Vec3f(1.0f / 11, 1.0f / 30, 1.0f / 11);
			
			ARX_DAMAGES_DamagePlayer(dmgs, 0, io_source->index());
			ARX_DAMAGES_DamagePlayerEquipment(dmgs);
			
		} else {
			
			Vec3f ppos = io_source->pos - io_target->pos;
			ppos = glm::normalize(ppos);
			
			// Push the NPC
			io_target->forcedmove += ppos * -dmgs;
			
			Vec3f * pos = position ? position : &io_target->pos;
			ARX_DAMAGES_DamageNPC(io_target, dmgs, io_source->index(), false, pos);
		}
	}
	
	return dmgs;
}
Beispiel #28
0
//*************************************************************************************
// flags & 1 == spell damage
//*************************************************************************************
float ARX_DAMAGES_DamageNPC(Entity * io, float dmg, EntityHandle source, bool isSpellHit, const Vec3f * pos) {
	
	if(   !io
	   || !io->show
	   || !(io->ioflags & IO_NPC)
	   || (io->ioflags & IO_INVULNERABILITY)
	) {
		return 0.f;
	}

	float damagesdone = 0.f;

	if(io->_npcdata->lifePool.current <= 0.f) {
		if(source != PlayerEntityHandle || (source == PlayerEntityHandle && player.equiped[EQUIP_SLOT_WEAPON] > 0)) {
			if(dmg >= io->_npcdata->lifePool.max * 0.4f && pos)
				ARX_NPC_TryToCutSomething(io, pos);

			return damagesdone;
		}

		return damagesdone;
	}

	io->dmg_sum += dmg;

	if(float(arxtime) > io->ouch_time + 500) {
		if(ValidIONum(source))
			EVENT_SENDER = entities[source];
		else
			EVENT_SENDER = NULL;

		io->ouch_time = (unsigned long)(arxtime);
		char tex[32];

		if(EVENT_SENDER && EVENT_SENDER->summoner == 0) {
			EVENT_SENDER = entities.player();
			sprintf(tex, "%5.2f summoned", io->dmg_sum);
		} else {
			sprintf(tex, "%5.2f", io->dmg_sum);
		}

		SendIOScriptEvent(io, SM_OUCH, tex);
		io->dmg_sum = 0.f;
		
		spells.endByTarget(io->index(), SPELL_CONFUSE);
	}

	if(dmg >= 0.f) {
		if(ValidIONum(source)) {
			Entity * pio = NULL;

			if(source == 0) {
				if(player.equiped[EQUIP_SLOT_WEAPON] != PlayerEntityHandle && ValidIONum(player.equiped[EQUIP_SLOT_WEAPON])) {
					pio = entities[player.equiped[EQUIP_SLOT_WEAPON]];

					if((pio && (pio->poisonous == 0 || pio->poisonous_count == 0)) || isSpellHit) {
						pio = NULL;
					}
				}
			} else {
				if(entities[source]->ioflags & IO_NPC) {
					pio = entities[source]->_npcdata->weapon;
					if(pio && (pio->poisonous == 0 || pio->poisonous_count == 0)) {
						pio = NULL;
					}
				}
			}

			if(!pio)
				pio = entities[source];

			if(pio && pio->poisonous && (pio->poisonous_count != 0)) {
				if(rnd() * 100.f > io->_npcdata->resist_poison) {
					io->_npcdata->poisonned += pio->poisonous;
				}

				if (pio->poisonous_count != -1)
					pio->poisonous_count--;
			}
		}

		if(io->script.data != NULL) {
			if(source >= PlayerEntityHandle) {
				if(ValidIONum(source))
					EVENT_SENDER = entities[source]; 
				else
					EVENT_SENDER = NULL;

				char dmm[256];

				if(EVENT_SENDER == entities.player()) {
					if(isSpellHit) {
						sprintf(dmm, "%f spell", dmg);
					}
					else
						switch (ARX_EQUIPMENT_GetPlayerWeaponType()) {
							case WEAPON_BARE:
								sprintf(dmm, "%f bare", dmg);
								break;
							case WEAPON_DAGGER:
								sprintf(dmm, "%f dagger", dmg);
								break;
							case WEAPON_1H:
								sprintf(dmm, "%f 1h", dmg);
								break;
							case WEAPON_2H:
								sprintf(dmm, "%f 2h", dmg);
								break;
							case WEAPON_BOW:
								sprintf(dmm, "%f arrow", dmg);
								break;
							default:
								sprintf(dmm, "%f", dmg);
								break;
						}
				}
				else
					sprintf(dmm, "%f", dmg);

				if(EVENT_SENDER && EVENT_SENDER->summoner == 0) {
					EVENT_SENDER = entities.player();
					sprintf(dmm, "%f summoned", dmg);
				}

				if(SendIOScriptEvent(io, SM_HIT, dmm) != ACCEPT)
					return damagesdone;
			}
		}

		damagesdone = std::min(dmg, io->_npcdata->lifePool.current);
		io->_npcdata->lifePool.current -= dmg;
		
		float fHitFlash = 0;
		if(io->_npcdata->lifePool.current <= 0) {
			fHitFlash = 0;
		} else {
			fHitFlash = io->_npcdata->lifePool.current / io->_npcdata->lifePool.max;
		}
		hitStrengthGaugeRequestFlash(fHitFlash);
		
		
		if(io->_npcdata->lifePool.current <= 0.f) {
			io->_npcdata->lifePool.current = 0.f;

			if(source != PlayerEntityHandle || (source == PlayerEntityHandle && player.equiped[EQUIP_SLOT_WEAPON] > 0)) {
				if((dmg >= io->_npcdata->lifePool.max * ( 1.0f / 2 )) && pos)
					ARX_NPC_TryToCutSomething(io, pos);
			}

			if(ValidIONum(source)) {
				long xp = io->_npcdata->xpvalue;
				ARX_DAMAGES_ForceDeath(io, entities[source]);

				if(source == 0 || entities[source]->summoner == 0)
					ARX_PLAYER_Modify_XP(xp);
			}
			else ARX_DAMAGES_ForceDeath(io, NULL);
		}
	}

	return damagesdone;
}
Beispiel #29
0
// source = -1 no source but valid pos
// source = 0  player
// source > 0  IO
static void ARX_DAMAGES_UpdateDamage(DamageHandle j, float tim) {
	
	DAMAGE_INFO & damage = damages[j];
	
	if(!damage.exist) {
		return;
	}
		
	if(damage.params.flags & DAMAGE_FLAG_FOLLOW_SOURCE) {
		if(damage.params.source == PlayerEntityHandle) {
			damage.params.pos = player.pos;
		} else if (ValidIONum(damage.params.source)) {
			damage.params.pos = entities[damage.params.source]->pos;
		}
	}
	
	float dmg;
	if(damage.params.flags & DAMAGE_NOT_FRAME_DEPENDANT) {
		dmg = damage.params.damages;
	} else if(damage.params.duration == -1) {
		dmg = damage.params.damages;
	} else {
		float FD = (float)framedelay;
		
		if(tim > damage.start_time + damage.params.duration) {
			FD -= damage.start_time + damage.params.duration - tim;
		}
		
		dmg = damage.params.damages * FD * ( 1.0f / 1000 );
	}
	
	bool validsource = ValidIONum(damage.params.source);
	float divradius = 1.f / damage.params.radius;
	
	// checking for IO damages
	for(size_t i = 0; i < entities.size(); i++) {
		const EntityHandle handle = EntityHandle(i);
		Entity * io = entities[handle];
		
		if(io
		   && (io->gameFlags & GFLAG_ISINTREATZONE)
		   && (io->show == SHOW_FLAG_IN_SCENE)
		   && (damage.params.source != long(i)
		   || (damage.params.source == long(i) && !(damage.params.flags & DAMAGE_FLAG_DONT_HURT_SOURCE)))
		){
			if(io->ioflags & IO_NPC) {
				if(   i != 0
				   && damage.params.source != PlayerEntityHandle
				   && validsource
				   && HaveCommonGroup(io, entities[damage.params.source])
				) {
					continue;
				}
				
				Sphere sphere;
				sphere.origin = damage.params.pos;
				sphere.radius = damage.params.radius - 10.f;
				
				if(CheckIOInSphere(sphere, EntityHandle(i), true)) {
					Vec3f sub = io->pos + Vec3f(0.f, -60.f, 0.f);
					
					float dist = fdist(damage.params.pos, sub);
					
					if(damage.params.type & DAMAGE_TYPE_FIELD) {
						if(float(arxtime) > io->collide_door_time + 500) {
							EVENT_SENDER = NULL;
							io->collide_door_time = (unsigned long)(arxtime); 
							char param[64];
							param[0] = 0;
							
							if(damage.params.type & DAMAGE_TYPE_FIRE)
								strcpy(param, "fire");
							
							if(damage.params.type & DAMAGE_TYPE_COLD)
								strcpy(param, "cold");
							
							SendIOScriptEvent(io, SM_COLLIDE_FIELD, param);
						}
					}
					
					switch(damage.params.area) {
						case DAMAGE_AREA: {
							float ratio = (damage.params.radius - dist) * divradius;
							ratio = glm::clamp(ratio, 0.f, 1.f);
							dmg = dmg * ratio + 1.f;
						}
						break;
						case DAMAGE_AREAHALF: {
							float ratio = (damage.params.radius - (dist * ( 1.0f / 2 ))) * divradius;
							ratio = glm::clamp(ratio, 0.f, 1.f);
							dmg = dmg * ratio + 1.f;
						}
						break;
						case DAMAGE_FULL:
						break;
					}
					
					if(dmg <= 0.f)
						continue;
					
					if(   (damage.params.flags & DAMAGE_FLAG_ADD_VISUAL_FX)
					   && (entities[handle]->ioflags & IO_NPC)
					   && (entities[handle]->_npcdata->lifePool.current > 0.f)
					) {
						ARX_DAMAGES_AddVisual(&damage, &sub, dmg, entities[handle]);
					}
					
					if(damage.params.type & DAMAGE_TYPE_DRAIN_MANA) {
						float manadrained;
						
						if(i == 0) {
							manadrained = std::min(dmg, player.manaPool.current);
							player.manaPool.current -= manadrained;
						} else {
							manadrained = dmg;
							
							if(io && io->_npcdata) {
								manadrained = std::min(dmg, io->_npcdata->manaPool.current);
								io->_npcdata->manaPool.current -= manadrained;
							}
						}
						
						if (damage.params.source == PlayerEntityHandle) {
							player.manaPool.current = std::min(player.manaPool.current + manadrained, player.Full_maxmana);
						} else {
							if(ValidIONum(damage.params.source) && (entities[damage.params.source]->_npcdata)) {
								entities[damage.params.source]->_npcdata->manaPool.current = std::min(entities[damage.params.source]->_npcdata->manaPool.current + manadrained, entities[damage.params.source]->_npcdata->manaPool.max);
							}
						}
					} else {
						float damagesdone;
						
						// TODO copy-paste
						if(i == 0) {
							if(damage.params.type & DAMAGE_TYPE_POISON) {
								if(rnd() * 100.f > player.m_misc.resistPoison) {
									// Failed Saving Throw
									damagesdone = dmg; 
									player.poison += damagesdone;
								} else {
									damagesdone = 0;
								}
							} else {
								if(   (damage.params.type & DAMAGE_TYPE_MAGICAL)
								   && !(damage.params.type & DAMAGE_TYPE_FIRE)
								   && !(damage.params.type & DAMAGE_TYPE_COLD)
								) {
									dmg -= player.m_miscFull.resistMagic * ( 1.0f / 100 ) * dmg;
									dmg = std::max(0.0f, dmg);
								}
								if(damage.params.type & DAMAGE_TYPE_FIRE) {
									dmg = ARX_SPELLS_ApplyFireProtection(entities.player(), dmg);
									ARX_DAMAGES_IgnitIO(entities.player(), dmg);
								}
								if(damage.params.type & DAMAGE_TYPE_COLD) {
									dmg = ARX_SPELLS_ApplyColdProtection(entities.player(), dmg);
								}
								damagesdone = ARX_DAMAGES_DamagePlayer(dmg, damage.params.type, damage.params.source);
							}
						} else {
							if(   (entities[handle]->ioflags & IO_NPC)
							   && (damage.params.type & DAMAGE_TYPE_POISON)
							) {
								if(rnd() * 100.f > entities[handle]->_npcdata->resist_poison) {
									// Failed Saving Throw
									damagesdone = dmg; 
									entities[handle]->_npcdata->poisonned += damagesdone;
								} else {
									damagesdone = 0;
								}
							} else {
								if(damage.params.type & DAMAGE_TYPE_FIRE) {
									dmg = ARX_SPELLS_ApplyFireProtection(entities[handle], dmg);
									ARX_DAMAGES_IgnitIO(entities[handle], dmg);
								}
								if(   (damage.params.type & DAMAGE_TYPE_MAGICAL)
								   && !(damage.params.type & DAMAGE_TYPE_FIRE)
								   && !(damage.params.type & DAMAGE_TYPE_COLD)
								) {
									dmg -= entities[handle]->_npcdata->resist_magic * ( 1.0f / 100 ) * dmg;
									dmg = std::max(0.0f, dmg);
								}
								if(damage.params.type & DAMAGE_TYPE_COLD) {
									dmg = ARX_SPELLS_ApplyColdProtection(entities[handle], dmg);
								}
								damagesdone = ARX_DAMAGES_DamageNPC(entities[handle], dmg, damage.params.source, true, &damage.params.pos);
							}
							if(damagesdone > 0 && (damage.params.flags & DAMAGE_SPAWN_BLOOD)) {
								ARX_PARTICLES_Spawn_Blood(&damage.params.pos, damagesdone, damage.params.source);
							}
						}
						if(damage.params.type & DAMAGE_TYPE_DRAIN_LIFE) {
							if(ValidIONum(damage.params.source))
								ARX_DAMAGES_HealInter(entities[damage.params.source], damagesdone);
						}
					}
				}
			} else if((io->ioflags & IO_FIX) && !(damage.params.type & DAMAGE_TYPE_NO_FIX)) {
				Sphere sphere;
				sphere.origin = damage.params.pos;
				sphere.radius = damage.params.radius + 15.f;
				
				if(CheckIOInSphere(sphere, EntityHandle(i))) {
					ARX_DAMAGES_DamageFIX(io, dmg, damage.params.source, true);
				}
			}
		}
	}
	
	if(damage.params.duration == -1)
		damage.exist = false;
	else if(tim > damage.start_time + damage.params.duration)
		damage.exist = false;
}
Beispiel #30
0
void TreatBackgroundDynlights() {

    ARX_PROFILE_FUNC();

    for(size_t i = 0; i < MAX_LIGHTS; i++) {
        EERIE_LIGHT *light = GLight[i];

        if(light && (light->extras & EXTRAS_SEMIDYNAMIC)) {

            float fMaxdist = player.m_telekinesis ? 850 : 300;

            if(!fartherThan(light->pos, ACTIVECAM->orgTrans.pos, fMaxdist)) {
                ComputeLight2DPos(light);
            } else {
                light->m_screenRect.max.x = -1;
                light->m_screenRect.min.x = 1;
            }

            if(!light->m_ignitionStatus) {
                // just extinguished
                if(lightHandleIsValid(light->m_ignitionLightHandle)) {
                    lightHandleGet(light->m_ignitionLightHandle)->exist = 0;
                    light->m_ignitionLightHandle = LightHandle();

                    for(size_t l = 0; l < entities.size(); l++) {
                        const EntityHandle handle = EntityHandle(l);
                        Entity * e = entities[handle];

                        if(e && (e->ioflags & IO_MARKER)) {
                            Vec3f _pos2 = GetItemWorldPosition(e);
                            if(!fartherThan(light->pos, _pos2, 300.f)) {
                                SendIOScriptEvent(e, SM_CUSTOM, "douse");
                            }
                        }
                    }
                }
            } else {
                // just light up
                if(!lightHandleIsValid(light->m_ignitionLightHandle)) {
                    for(size_t l = 0; l < entities.size(); l++) {
                        const EntityHandle handle = EntityHandle(l);
                        Entity * e = entities[handle];

                        if(e && (e->ioflags & IO_MARKER)) {
                            Vec3f _pos2 = GetItemWorldPosition(e);
                            if(!fartherThan(light->pos, _pos2, 300.f)) {
                                SendIOScriptEvent(e, SM_CUSTOM, "fire");
                            }
                        }
                    }

                    light->m_ignitionLightHandle = GetFreeDynLight();
                }

                if(lightHandleIsValid(light->m_ignitionLightHandle)) {
                    EERIE_LIGHT *dynamicLight = lightHandleGet(light->m_ignitionLightHandle);

                    dynamicLight->pos          = light->pos;
                    dynamicLight->fallstart    = light->fallstart;
                    dynamicLight->fallend      = light->fallend;
                    dynamicLight->m_isIgnitionLight  = true;
                    dynamicLight->intensity    = light->intensity;
                    dynamicLight->ex_flaresize = light->ex_flaresize;
                    dynamicLight->extras       = light->extras;
                    dynamicLight->duration     = std::numeric_limits<long>::max();

                    dynamicLight->rgb = light->rgb - light->rgb * light->ex_flicker * randomColor3f() * 0.5f;

                    dynamicLight->rgb = componentwise_max(dynamicLight->rgb, Color3f::black);
                    RecalcLight(dynamicLight);
                }
            }
        }
    }

    for(size_t i = 0; i < MAX_DYNLIGHTS; i++) {
        EERIE_LIGHT * el = &DynLight[i];

        if(el->exist && el->duration) {
            float tim = (float)float(arxtime) - (float)el->time_creation;
            float duration = (float)el->duration;

            if(tim >= duration) {
                float sub = framedelay * 0.001f;

                el->rgb.r -= sub;
                el->rgb.g -= sub;
                el->rgb.b -= sub;

                if(el->rgb.r < 0)
                    el->rgb.r = 0.f;

                if(el->rgb.g < 0)
                    el->rgb.g = 0.f;

                if(el->rgb.b < 0)
                    el->rgb.b = 0.f;

                if(el->rgb.r + el->rgb.g + el->rgb.b == 0) {
                    el->exist = 0;
                    el->duration = 0;
                }
            }
        }
    }
}